POJ-3621 Sightseeing Cows 最优比率环、01分数规划

  题目链接:http://poj.org/problem?id=3621

  这题是01分数规划问题,详细资料点这里。有了01分数规划的基础后,这个题目就很简单了。构建函数f(mid)=Σ(w[i]-mid*d[i]),然后二分mid,如果图中有正权环,则f(mid)>0,则还有更优解l=mid,否则r=mid。

 1 //STATUS:C++_AC_563MS_296KB
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<string>
 8 #include<algorithm>
 9 #include<vector>
10 #include<queue>
11 #include<stack>
12 using namespace std;
13 #define LL __int64
14 #define pii pair<int,int>
15 #define Max(a,b) ((a)>(b)?(a):(b))
16 #define Min(a,b) ((a)<(b)?(a):(b))
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define lson l,mid,rt<<1
19 #define rson mid+1,r,rt<<1|1
20 const int N=1010,M=1000000,INF=0x3f3f3f3f,MOD=1999997;
21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL;
22 const double DNF=100000000;
23 
24 struct Edge{
25     int u,v,w;
26 }e[5*N];
27 double d[N];
28 int w[N],inq[N],first[N],next[5*N],cou[N];
29 int n,m,mt;
30 
31 void adde(int a,int b,int c)
32 {
33     e[mt].u=a,e[mt].v=b,e[mt].w=c;
34     next[mt]=first[a],first[a]=mt++;
35 }
36 
37 int SPFA(int s,double mid)
38 {
39     int i,j,u,v;
40     queue<int> q;
41     for(i=1;i<=n;i++)d[i]=-DNF;d[s]=0;
42     mem(inq,0);mem(cou,0);
43     q.push(s);
44     while(!q.empty()){
45         u=q.front();q.pop();
46         inq[u]=0;
47         for(i=first[u];i!=-1;i=next[i]){
48             v=e[i].v;
49             if(d[u]+w[u]-e[i].w*mid>d[v]){
50                 d[v]=d[u]+w[u]-e[i].w*mid;
51                 if(!inq[v]){
52                     inq[v]=1;
53                     if(++cou[v]==n)return 1;
54                     q.push(v);
55                 }
56             }
57         }
58     }
59     return 0;
60 }
61 
62 double binary()
63 {
64     double l=0,r=1000,mid;
65     while(r-l>1e-3){
66         mid=l+(r-l)/2;
67         if(SPFA(1,mid)>0)l=mid;
68         else r=mid;
69     }
70     return mid;
71 }
72 
73 int main()
74 {
75   //  freopen("in.txt","r",stdin);
76     int i,j,a,b,c;
77     while(~scanf("%d%d",&n,&m))
78     {
79         mt=0;
80         mem(first,-1);
81         for(i=1;i<=n;i++)
82             scanf("%d",&w[i]);
83         for(i=0;i<m;i++){
84             scanf("%d%d%d",&a,&b,&c);
85             adde(a,b,c);
86         }
87 
88         printf("%.2lf\n",binary());
89     }
90     return 0;
91 }

 

posted @ 2013-01-29 16:12  zhsl  阅读(264)  评论(0编辑  收藏  举报