UVA - 11090 Going in Cycle!!
Posted 晓风微微
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA - 11090 Going in Cycle!!相关的知识,希望对你有一定的参考价值。
题意:
给一个有向图,问这个图构成的所有的环中,平均权值最小是多少?
平均权值是,回路上权值和除以边数。
分析:
二分答案,让每条边减去二分的值,然后用Bellman-Ford算法,判断负环即可。
坑点:
如果判断出队次数,则要看是否大于n次,如果判断入队次数,则要看是否大于等于n次。
代码:
1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 #include<cmath> 5 #include<vector> 6 #include<cstring> 7 #include<queue> 8 #define MAXN 500 9 typedef long long LL; 10 int ii=0; 11 struct teamdata{ 12 double d;int point; 13 bool operator<(const teamdata& pt)const{ 14 return this->d>pt.d; 15 } 16 }; 17 struct bian{ 18 int point; 19 double d; 20 }; 21 int n,m,k,l,s,t; 22 vector<bian> maps[MAXN]; 23 const double inf=1e10; 24 double d[MAXN]; 25 int pre[MAXN]; 26 priority_queue<teamdata> team; 27 int v[MAXN]; 28 int SPFA(double mid){ 29 LL ans=-1; 30 teamdata pt; 31 while(!team.empty()) team.pop(); 32 teamdata pd; 33 for (int i=0;i<=MAXN-1;i++) d[i]=inf,pre[i]=0,v[i]=0;d[s]=0; 34 for (int i=1;i<=n;i++) { 35 pt.d=0;pt.point=i;team.push(pt);d[i]=0;v[i]=1; 36 } 37 while(!team.empty()){ 38 pt=team.top();team.pop(); 39 //cout<<"*"<<pt.point<<" "<<pt.d<<endl; 40 v[pt.point]=0; 41 for (int i=0;i<maps[pt.point].size();i++){ 42 int nb=maps[pt.point][i].point; 43 if (d[nb]>d[pt.point]+maps[pt.point][i].d-mid){ 44 d[nb]=d[pt.point]+maps[pt.point][i].d-mid; 45 pd.d=d[nb];pd.point=nb; 46 if (v[nb]==0){ 47 v[nb]=1; 48 //printf("\t%d %lf %lf\n",pd.point,pd.d,mid); 49 team.push(pd); 50 pre[nb]++; 51 if (pre[nb]>=n) { 52 return 1; 53 } 54 } 55 } 56 } 57 } 58 return 0; 59 } 60 void deal(){ 61 scanf("%d%d",&n,&m); 62 double w; 63 for (int i=0;i<=n;i++) maps[i].clear(); 64 double ll=0; 65 for (int i=1;i<=m;i++){ 66 int l,r; 67 scanf("%d%d%lf",&l,&r,&w); 68 bian pt;pt.d=w;pt.point=r; 69 ll=max(ll,w); 70 maps[l].push_back(pt); 71 } 72 double l,r,mid,ans=1e9; 73 l=0;r=ll+1; 74 if (SPFA(ll+1)==0){ 75 printf("No cycle found.\n"); 76 return; 77 } 78 else 79 while((r-l)>1e-10){ 80 mid=(l+r)/2; 81 int zans=0; 82 zans=SPFA(mid); 83 if (zans){ 84 if (mid<ans) ans=mid; 85 r=mid; 86 }else{ 87 l=mid; 88 } 89 } 90 printf("%.2lf\n",ans); 91 } 92 int main(){ 93 int t; 94 scanf("%d",&t); 95 while(t--){ 96 ii++; 97 printf("Case #%d: ",ii); 98 deal(); 99 } 100 return 0; 101 }
以上是关于UVA - 11090 Going in Cycle!!的主要内容,如果未能解决你的问题,请参考以下文章
UVA11090 Going in Cycle!! [spfa负环]
Going in Cycle!! UVA - 11090(二分+判断环路 )