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 }

 

你可能感兴趣的:(poj)