poj3686The Windy's (KM)

http://poj.org/problem?id=3686

拆点很巧妙 将每个M个点拆成m*n个点 分别表示第i个玩具在第j个机器上倒数第K个处理 

假设这k个玩具真正用在加工的时间分为a1,a2,a3...ak, 那么每个玩具实际的时间是加工的时间+等待时间,分别为

a1, a1+a2, a1+a2+a3.......a1+a2+...ak   

求和之后变为 a1 *k + a2 * (k - 1) + a3 * (k - 2).... + ak

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<stdlib.h>
 7 #define INF 0xfffffff
 8 #define N 55
 9 #define M 2555
10 using namespace std;
11 int w[N][M],n,m,p,lx[N],d,ly[M],link[M],x[N],y[M];
12 bool match(int u)
13 {
14     x[u] = 1;
15     for(int i = 1; i <= p ; i++)
16     {
17         if(y[i]) continue;
18         int o = lx[u]+ly[i]-w[u][i];
19         if(o==0)
20         {
21             y[i] = 1;
22             if(!link[i]||match(link[i]))
23             {
24                 link[i] = u;
25                 return true;
26             }
27         }
28         else if(o<d) d = o;
29     }
30     return false;
31 }
32 void km()
33 {
34     int i,j;
35     for(i = 1 ;i <= n ;i++)
36     lx[i] = -INF;
37     memset(ly,0,sizeof(ly));
38     memset(link,0,sizeof(link));
39     for(i = 1; i <= n ;i++)
40         for(j = 1; j <= p ;j++)
41         lx[i] = max(lx[i],w[i][j]);
42     for(i = 1; i <= n ;i++)
43     {
44         for(;;)
45         {
46             d = INF;
47             memset(x,0,sizeof(x));
48             memset(y,0,sizeof(y));
49             if(match(i)) break;
50             for(j =1 ;j <= n ;j++) if(x[j]){lx[j]-=d;}
51             for(j =1 ;j <= p ;j++) if(y[j]){ly[j]+=d;}
52         }
53     }
54 }
55 int main()
56 {
57     int cas,i,j,k,a;
58     cin>>cas;
59     while(cas--)
60     {
61         scanf("%d%d",&n,&m);
62         for(i = 1 ;i <= n ;i++)
63             for(j = 1 ;j <= m ; j++)
64             {
65                 scanf("%d",&a);
66                 for(k = 1 ; k <= n ;k++)
67                 w[i][(j-1)*n+k] = -1*k*a;
68             }
69         p = n*m;
70         double s=0;
71         km();
72 
73         for(i = 1 ;i <= p ; i++)
74         if(link[i])
75         {
76            s-=w[link[i]][i];
77         }
78         printf("%.6f
",1.0*s/n);
79     }
80     return 0;
81 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3159638.html