POJ 3621-Sightseeing Cows-最优比率环|SPFA+二分

最优比率环问题。二分答案,对于每一个mid,把节点的happy值归类到边上。

对于每条边,用mid×weight减去happy值,如果不存在负环,说明还可以更大。

  1 /*--------------------------------------------------------------------------------------*/
  2 //        Helica's header
  3 //        Second Edition
  4 //        2015.11.7
  5 //
  6 #include <algorithm>
  7 #include <iostream>
  8 #include <cstring>
  9 #include <ctype.h>
 10 #include <cstdlib>
 11 #include <cstdio>
 12 #include <vector>
 13 #include <string>
 14 #include <queue>
 15 #include <stack>
 16 #include <cmath>
 17 #include <set>
 18 #include <map>
 19 
 20 //debug function for a N*M array
 21 #define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++)\
 22 {for(int j=0;j<(M);j++){\
 23 printf("%d",G[i][j]);}printf("\n");}
 24 //debug function for int,float,double,etc.
 25 #define debug_var(X) cout<<#X"="<<X<<endl;
 26 /*--------------------------------------------------------------------------------------*/
 27 using namespace std;
 28 
 29 const int INF = 0x3f3f3f3f;
 30 const int maxn = 1e3+100;
 31 const double eps = 1e-3;
 32 int N,M;
 33 int happy[maxn];
 34 
 35 struct Edge
 36 {
 37     int to,next,w;
 38 }edge[10*maxn];
 39 
 40 int head[maxn],cnt[maxn],tol;
 41 double dist[maxn];
 42 bool vis[maxn];
 43 
 44 bool SPFA(double mid)
 45 {
 46     memset(vis,false,sizeof(vis));
 47     memset(cnt,0,sizeof(cnt));
 48     for(int i=1;i<=N;i++)dist[i]=INF;
 49     dist[1]=0;
 50     queue<int>Q;
 51     Q.push(1);
 52     while(!Q.empty()){
 53         int u=Q.front();
 54         Q.pop();
 55         vis[u]=false;
 56         cnt[u]++;
 57         if(cnt[u]>N)return true;
 58         for(int i=head[u];i!=-1;i=edge[i].next){
 59             int v=edge[i].to,w=edge[i].w;
 60             double tmp=mid*w-happy[v];
 61             if(dist[u]+tmp<dist[v]){
 62                 dist[v]=dist[u]+tmp;
 63                 if(!vis[v]){ vis[v]=true;Q.push(v); }
 64             }
 65         }
 66     }
 67     return false;
 68 }
 69 void add_edge(int u,int v,int w)
 70 {
 71     edge[tol].to = v;
 72     edge[tol].w = w;
 73     edge[tol].next = head[u];
 74     head[u] = tol++;
 75 }
 76 
 77 int main()
 78 {
 79     //freopen("input.in","r",stdin);
 80     while(~scanf("%d%d",&N,&M))
 81     {
 82         memset(head,-1,sizeof head);
 83         tol = 0;
 84         for(int i=1;i<=N;i++)    scanf("%d",&happy[i]);
 85         for(int i=0,u,v,w;i<M;i++)
 86         {
 87             scanf("%d%d%d",&u,&v,&w);
 88             add_edge(u,v,w);
 89         }
 90         double L = 0,R = 10000.0,mid;
 91 
 92         while(abs(L-R)>eps)
 93         {
 94             mid = (L+R)/2.0;
 95             if(SPFA(mid)) L = mid;
 96             else          R = mid;
 97         }
 98 
 99         printf("%.2f\n",mid);
100     }
101 }

 

posted @ 2016-03-06 16:47  Helica  阅读(251)  评论(0编辑  收藏  举报