poj 3686 The Windy's

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

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #define maxn 30000
  5 using namespace std;
  6 
  7 const int inf=1<<30;
  8 int weight[51][maxn],lx[maxn],ly[maxn],match[maxn],a[51][51];
  9 bool sx[maxn],sy[maxn];
 10 
 11 int n,m;
 12 
 13 bool path(int u)
 14 {
 15     sx[u]=true;
 16     for(int v=1; v<=n*m; v++)
 17     {
 18         if(!sy[v]&&lx[u]+ly[v]==weight[u][v])
 19         {
 20             sy[v]=true;
 21             if(!match[v]||path(match[v]))
 22             {
 23                 match[v]=u;
 24                 return true;
 25             }
 26         }
 27     }
 28     return false;
 29 }
 30 
 31 int bestmatch()
 32 {
 33     memset(lx,-inf,sizeof(lx));
 34     memset(ly,0,sizeof(ly));
 35     memset(match,0,sizeof(match));
 36     for(int i=1; i<=n; i++)
 37     {
 38         for(int j=1; j<=n*m; j++)
 39         {
 40             lx[i]=max(lx[i],weight[i][j]);
 41         }
 42     }
 43     for(int u=1; u<=n; u++)
 44     {
 45         while(1)
 46         {
 47             memset(sx,false,sizeof(sx));
 48             memset(sy,false,sizeof(sy));
 49             if(path(u)) break;
 50             int dx=inf;
 51             for(int i=1; i<=n; i++)
 52             {
 53                 if(sx[i])
 54                 {
 55                     for(int j=1; j<=n*m; j++)
 56                     {
 57                         if(!sy[j]) dx=min(lx[i]+ly[j]-weight[i][j],dx);
 58                     }
 59                 }
 60             }
 61             for(int i=1; i<=n; i++)
 62             {
 63                 if(sx[i]) lx[i]-=dx;
 64             }
 65             for(int j=1; j<=n*m; j++)
 66             {
 67                 if(sy[j]) ly[j]+=dx;
 68             }
 69         }
 70 
 71     }
 72     int sum=0;
 73     for(int i=1; i<=n*m; i++)
 74             sum+=weight[match[i]][i];
 75     return -sum;
 76 }
 77 int main()
 78 {
 79     int T;
 80     scanf("%d",&T);
 81     while(T--)
 82     {
 83         scanf("%d%d",&n,&m);
 84         for(int i=1; i<=n; i++)
 85         {
 86             for(int j=1; j<=m; j++)
 87             {
 88                 scanf("%d",&a[i][j]);
 89             }
 90         }
 91         for(int i=1; i<=n; i++)
 92         {
 93             for(int j=1; j<=n; j++)
 94             {
 95                 for(int k=1; k<=m; k++)
 96                 {
 97                     weight[i][(k-1)*n+j]=-a[i][k]*j;
 98                 }
 99             }
100         }
101         printf("%.6f
",1.0*bestmatch()/n);
102     }
103     return 0;
104 }
View Code
原文地址:https://www.cnblogs.com/fanminghui/p/3554451.html