3686

1 /*
2 这个题目有点意思,并不是求总共需要多长时间来完成订单,
3 而是要求完成顶点的总时间。
4
5 这个总时间是包括订单的等待时间的
6
7 因为有可能有多个订单都要到工厂j去完成,那么就浪费了很多时间,这些时间也算是总时间里面的
8
9 所以。每个工厂有可能有N个订单在等待来完成,所以工厂要拆开成N个点来构图
10
11 注意此题的左右顶点不同,和传统的KM写的时候要注意点,不然会TLE或者WA的不明不白
12 */
13
14 // include file
15 #include <cstdio>
16 #include <cstdlib>
17 #include <cstring>
18 #include <cmath>
19 #include <cctype>
20 #include <ctime>
21
22 #include <iostream>
23 #include <sstream>
24 #include <fstream>
25 #include <iomanip>
26 #include <bitset>
27 #include <strstream>
28
29 #include <algorithm>
30 #include <string>
31 #include <vector>
32 #include <queue>
33 #include <set>
34 #include <list>
35 #include <functional>
36
37 using namespace std;
38
39 // typedef
40 typedef long long LL;
41 typedef unsigned long long ULL;
42
43 //
44 #define read freopen("in.txt","r",stdin)
45 #define write freopen("out.txt","w",stdout)
46 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
47 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
48 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
49 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
50 #define FORii(a,b,c) for(int ii=(a);ii<(b);ii+=c)
51 #define FORjj(a,b,c) for(int jj=(a);jj<(b);jj+=c)
52 #define FORkk(a,b,c) for(int kk=(a);kk<(b);kk+=c)
53
54 #define FF(i,a) for(int i=0;i<(a);i+++)
55 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
56 #define Z(a) (a<<1)
57 #define Y(a) (a>>1)
58
59 const double eps = 1e-6;
60 const double INFf = 1e10;
61 const int INFi = 1000000000;
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 55
89 int Cas,N,M;
90 int cost[MAXN][MAXN];
91 int costn[MAXN][MAXN*MAXN];
92 int lx[MAXN];
93 int ly[MAXN*MAXN];
94 int S[MAXN];
95 int T[MAXN*MAXN];
96 int mt[MAXN*MAXN];
97 int mz[MAXN];
98
99 bool hungarian_MM(int i)
100 {
101 S[i] = true;
102 FORj(0,M,1)
103 {
104 if(!T[j] && lx[i]+ly[j]==costn[i][j])
105 {
106 T[j] = true;
107 if( mt[j]==-1 || hungarian_MM(mt[j]))
108 {
109 mz[i] = j;
110 mt[j] = i;
111 return true;
112 }
113 }
114 }
115 return false;
116 }
117
118 int KM_PM(bool flag=true)//true时是最大值,否则是最小值
119 {
120 if(!flag)
121 {
122 FORi(0,N,1)
123 {
124 FORj(0,M,1)
125 {
126 costn[i][j] = -costn[i][j];
127 }
128 }
129 }
130
131 // 初始化顶标
132 FORi(0,N,1)
133 {
134 lx[i]=-INFi;
135 FORj(0,M,1)
136 {
137 ly[j] = 0;
138 lx[i] = TMAX(lx[i],costn[i][j]);
139 }
140 }
141
142 memset(mz,-1,sizeof(mz));
143 memset(mt,-1,sizeof(mt));
144
145 FORi(0,N,1)
146 {
147 while(true)
148 {
149 memset(S,0,sizeof(S));
150 memset(T,0,sizeof(T));
151 if( hungarian_MM(i) )
152 break;
153
154 // d
155 int d = INFi;
156 FORj(0,N,1)
157 {
158 if(S[j])
159 FORk(0,M,1)
160 {
161 if(!T[k])
162 {
163 d = TMIN(d,lx[j]+ly[k]-costn[j][k]);
164 }
165 }
166 }
167
168 ///
169 FORj(0,N,1)
170 {
171 if(S[j])
172 lx[j] -= d;
173 }
174 FORj(0,M,1)
175 {
176 if(T[j])
177 ly[j] += d;
178 }
179 }
180 }
181
182 //
183 int ans = 0;
184 FORi(0,N,1)
185 {
186
187 ans+=costn[i][mz[i]];
188
189 }
190
191 if(!flag)
192 {
193 ans = -ans;
194 }
195 return ans;
196 }
197
198 int main()
199 {
200 read;
201 write;
202 scanf("%d",&Cas);
203 while(Cas--)
204 {
205 scanf("%d %d",&N,&M);
206 FORi(0,N,1)
207 {
208 FORj(0,M,1)
209 {
210 scanf("%d",&cost[i][j]);
211 }
212 }
213
214 //
215 FORi(0,N,1)
216 {
217 FORj(0,M,1)
218 {
219 FORk(0,N,1)
220 {
221 costn[i][j*N+k] = -(k*cost[i][j]+cost[i][j]);
222 }
223 }
224 }
225
226 M = M*N;
227 int ans = -KM_PM();
228 printf("%.6f\n",(ans+0.0)/(N+0.0));
229 }
230 return 0;
231 }
posted @ 2011-03-07 20:33  AC2012  阅读(893)  评论(0编辑  收藏  举报