二分图 最佳匹配 最大权匹配

二分图 最佳匹配 最大权匹配
whummd 发表于 2006-7-29 16:31:00

转化成一个完美图,用匈牙利算法找增广路实现最大匹配,从而求出最佳匹配,优点是代码量比较少。方便调试。
速度也比较快
算法复杂度为n^3

用pku2195测试了一下时间为0ms

#i nclude<iostream>
using namespace std;
const int maxn=110;
const int maxint=100000000;
int map[maxn][maxn],link[maxn],lx[maxn],ly[maxn];
bool x[maxn],y[maxn];
int n,m;

int find(int v)
{
    int j,k;
    x[v]=1;
    for(j=1;j<=n;j++)
     if(y[j]==0&&lx[v]+ly[j]==map[v][j])
     {
        y[j]=1;
        k=link[j];link[j]=v;
        if(k==0||find(k))return 1;
        link[j]=k;
     }
    return 0;
}
int main()
{
freopen("a.in","r",stdin);freopen("a.out","w",stdout);
int i,j,k,d,ans;
while(scanf("%d%d",&n,&m)==2)
{
   memset(map,0,sizeof(map));
   memset(link,0,sizeof(link));
   memset(lx,0,sizeof(lx));   memset(ly,0,sizeof(ly));
   while(m--){  scanf("%d%d%d",&i,&j,&k); map[i][j]=k;}
   //这是最大匹配 最佳匹配就转为负值 map[i][j]=-k;当然输出也是是-ans啦
   for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
     if(map[i][j]>lx[i])lx[i]=map[i][j];
    
   for(k=1;k<=n;k++)
   do{
      memset(x,0,sizeof(x));memset(y,0,sizeof(y));
      if(find(k))break;
      d=maxint;
      for(i=1;i<=n;i++)
      if(x[i])
       for(j=1;j<=n;j++)
        if(!y[j]&&lx[i]+ly[j]-map[i][j]<d)
           d=lx[i]+ly[j]-map[i][j];
      for(i=1;i<=n;i++){if(x[i])lx[i]-=d;if(y[i])ly[i]+=d;}
   }while(1);
  
   for(ans=0,i=1;i<=n;i++)ans+=map[link[i]][i];
   printf("%d/n",ans);
}

return 0;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值