poj2400Supervisor, Supervisee(KM)

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

KM算法http://philoscience.iteye.com/blog/1754498

题意:每个雇主对雇员有个满意度 雇员对雇主有个满意度 求最匹配的雇员与雇主

最小权匹配 这个给出的数据矩阵貌似是反着的 建图的时候反一下就好了

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<stdlib.h>
  7 #define N 110
  8 #define INF 0x3f3f3f
  9 using namespace std;
 10 int w[N][N],n,x[N],y[N],lx[N],ly[N],link[N],sum,o[N],vis[N],num;
 11 bool match(int u)
 12 {
 13     x[u] = 1;
 14     for(int i = 1; i <= n ; i++)
 15     if(lx[u]+ly[i]==w[u][i]&&!y[i])
 16     {
 17         y[i] = 1;
 18         if(!link[i]||match(link[i]))
 19         {
 20             link[i] = u;
 21             return true;
 22         }
 23     }
 24     return false;
 25 }
 26 double km()
 27 {
 28     int i,j,g;
 29     for(i = 1; i <= n ; i++)
 30     link[i] = lx[i] = ly[i]=0;
 31     for(i = 1 ; i <= n ; i++)
 32     {
 33         for(;;)
 34         {
 35             for(j = 1 ;j <= n ; j++)
 36             x[j] = y[j] = 0;
 37             if(match(i)) break;
 38             int d = INF;
 39             for(j = 1; j <= n ; j++)
 40             {
 41                 if(x[j])
 42                 for(g = 1; g <= n ; g++)
 43                 if(!y[g])
 44                 d = min(d,lx[j]+ly[g]-w[j][g]);
 45             }
 46             for(j = 1; j <= n ; j++)
 47             {
 48                 if(x[j]) lx[j]-=d;
 49                 if(y[j]) ly[j]+=d;
 50             }
 51         }
 52     }
 53     sum=0;
 54     for(i = 1; i <= n ; i++)
 55     sum-=(lx[i]+ly[i]);
 56     return 1.0*sum/(2*n);
 57 }
 58 void dfs(int u,int ss)
 59 {
 60     int i;
 61     if(ss>sum) return ;
 62     if(u==n+1)
 63     {
 64         printf("Best Pairing %d\n",++num);
 65         for(i = 1 ;i <= n ; i++)
 66         printf("Supervisor %d with Employee %d\n",i,o[i]);
 67         return ;
 68     }
 69     for(i = 1; i <= n ; i++)
 70     {
 71         if(!vis[i])
 72         {
 73             vis[i] = 1;
 74             o[u] = i;
 75             dfs(u+1,ss-w[u][i]);
 76             vis[i] = 0;
 77         }
 78     }
 79 }
 80 int main()
 81 {
 82     int i,j,kk=0,cas,a;
 83     scanf("%d",&cas);
 84     while(cas--)
 85     {
 86         kk++;num=0;
 87         scanf("%d",&n);
 88         memset(w,0,sizeof(w));
 89         memset(vis,0,sizeof(vis));
 90         for(i = 1 ; i <= n ; i++)
 91             for(j = 1; j <= n ; j++)
 92             {
 93                 scanf("%d",&a);
 94                 w[a][i] -= j;
 95             }
 96         for(i = 1 ; i <= n ; i++)
 97             for(j = 1; j <= n ; j++)
 98             {
 99                 scanf("%d",&a);
100                 w[i][a]-=j;
101             }
102         double s = km();
103         printf("Data Set %d, Best average difference: %.6f\n",kk,s-1);
104         dfs(1,0);
105         puts("");
106     }
107     return 0;
108 }
View Code

 

posted @ 2013-06-23 17:04  _雨  阅读(317)  评论(0编辑  收藏  举报