您的位置:首页 > 其它

poj 2400(最小权匹配)

2012-05-12 23:19 375 查看
题意:给出雇主对雇员的满意度和雇员对雇主的满意度,分数越低代表评价越高,求给出最优匹配方案。当有多种最优匹配,全部输出!

思路:典型的最小权匹配,km算法求解

View Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define N 111
int net

,x
,y
,lx
,ly
,link
,b
,like
;
int n,sum,d,cnt;
bool km_dfs(int u)
{
x[u]=1;
for(int i=1;i<=n;i++)
{
if(y[i])continue;
int t=lx[u]+ly[i]-net[u][i];
if(t==0)
{
y[i]=1;
if(!link[i]||km_dfs(link[i]))
{
link[i]=u;
return true;
}
}
else d=min(d,t);
}
return false;
}
double km()
{
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
memset(link,0,sizeof(link));
for(int i=1;i<=n;i++)
{
while(1){
d=inf;
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
if(km_dfs(i))break;
for(int j=1;j<=n;j++)
{
if(x[j])lx[j]-=d;
if(y[j])ly[j]+=d;
}
}
}
sum=0;
for(int i=1;i<=n;i++)
{
sum-=lx[i]+ly[i];
}
return 1.0*sum/(n*2);
}
void dfs(int step,int total)
{
if(total>sum)return ;
if(step==n+1)
{
printf("Best Pairing %d\n",cnt++);
for(int i=1;i<=n;i++)
printf("Supervisor %d with Employee %d\n",i,like[i]);
return ;
}
for(int i=1;i<=n;i++)
{
if(!b[i]){
b[i]=1;
like[step]=i;
dfs(step+1,total-net[step][i]);
b[i]=0;
}
}
}
int main()
{
int ca;
scanf("%d",&ca);
int cas=1;
while(ca--)
{
int x;
cnt=1;
memset(net,0,sizeof(net));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&x);
net[x][i]-=j;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&x);
net[i][x]-=j;//最小权匹配取负数
}
}
double ans=km();
printf("Data Set %d, Best average difference: %.6lf\n",cas++,ans-1);
memset(b,0,sizeof(b));
dfs(1,0);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: