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

 

你可能感兴趣的:(super)