3621

1 /*
2 01分数规划
3 分数规划
4 Dinkelbach算法
5
6 sigma(点权)/sigma(边权) <= lamda
7
8 sigma(F)/sigma(T) <= lamda
9
10 L = sigma(点) - lamda*sigma(边);
11
12 最终是个环
13
14 SPFA可以快速的检测是否存在负环,也就是说lamda值是否可行
15
16 此题和2728非常的类似,自己实现queue速度会快点
17 */
18
19
20 // include file
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 #include <cmath>
25 #include <cctype>
26 #include <ctime>
27
28 #include <iostream>
29 #include <sstream>
30 #include <fstream>
31 #include <iomanip>
32 #include <bitset>
33 #include <strstream>
34
35 #include <algorithm>
36 #include <string>
37 #include <vector>
38 #include <queue>
39 #include <set>
40 #include <list>
41 #include <functional>
42
43 using namespace std;
44
45 // typedef
46 typedef long long LL;
47 typedef unsigned long long ULL;
48
49 //
50 #define read freopen("in.txt","r",stdin)
51 #define write freopen("out.txt","w",stdout)
52 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
53 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
54
55 #define FF(i,a) for(int i=0;i<(a);i+++)
56 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
57 #define Z(a) (a<<1)
58 #define Y(a) (a>>1)
59
60 const double eps = 1e-6;
61 const double INF = 1e10;
62 const double Pi = acos(-1.0);
63
64 template<class T> inline T sqr(T a){return a*a;}
65 template<class T> inline T TMAX(T x,T y)
66 {
67 if(x>y) return x;
68 return y;
69 }
70 template<class T> inline T TMIN(T x,T y)
71 {
72 if(x<y) return x;
73 return y;
74 }
75 template<class T> inline void SWAP(T &x,T &y)
76 {
77 T t = x;
78 x = y;
79 y = t;
80 }
81 template<class T> inline T MMAX(T x,T y,T z)
82 {
83 return TMAX(TMAX(x,y),z);
84 }
85
86
87 // code begin
88 #define MAXN 1100
89
90 int N,M;
91 int F[MAXN];
92 struct node
93 {
94 int e;
95 double T;
96 double T2;
97 };
98
99 vector<node> G[MAXN];
100
101 double dst[MAXN]; //
102 int pre[MAXN];
103 bool isin[MAXN]; // 是否在队列中
104 int cnt[MAXN]; // 进入队列的次数
105 int qi[MAXN*MAXN];
106
107 bool BF_queue(double lamda)
108 {
109 FORi(1,N+1,1) dst[i] = INF;
110 memset(pre,0,sizeof(pre));
111 memset(isin,0,sizeof(isin));
112 memset(cnt,0,sizeof(cnt));
113
114 int head=0;
115 int tail=0;
116 qi[tail++] = 1;
117 pre[1] = -1;
118 isin[1] = 1;
119 cnt[1] = 1;
120 dst[1] = 0;
121
122 while(head<tail)
123 {
124 int cur = qi[head++];
125
126 isin[cur] = false;
127
128 FORi(0,G[cur].size(),1)
129 {
130
131 if( dst[cur]+lamda*G[cur][i].T-F[G[cur][i].e]<dst[G[cur][i].e] )
132 {
133 dst[G[cur][i].e] = dst[cur]+lamda*G[cur][i].T-F[G[cur][i].e];
134 pre[G[cur][i].e] = cur;
135 if( !isin[G[cur][i].e] )
136 {
137 isin[G[cur][i].e] = true;
138 cnt[G[cur][i].e] ++;
139 qi[tail++]=G[cur][i].e;
140 if( cnt[G[cur][i].e]>=N )
141 return true;
142 }
143 }
144
145 }
146 }
147 return false;
148 }
149
150 int main()
151 {
152 read;
153 write;
154 double L,R;
155 while(scanf("%d %d",&N,&M)!=-1)
156 {
157 L = 0;
158 R = 0;
159 FORi(1,N+1,1)
160 {
161 scanf("%d",&F[i]);
162 R += F[i];
163 G[i].clear();
164 }
165 int s,e;
166 double T;
167 FORi(0,M,1)
168 {
169 scanf("%d %d %lf",&s,&e,&T);
170 node t;
171 t.e = e;
172 t.T = T;
173 G[s].push_back(t);
174 }
175
176 while( R-L>eps)
177 {
178 double mid = (L+R)/2;
179 if( BF_queue(mid) ) L=mid;
180 else R=mid;
181 }
182
183 printf("%.2f\n",L);
184 }
185 return 0;
186 }
posted @ 2011-03-02 21:23  AC2012  阅读(1349)  评论(0编辑  收藏  举报