您的位置:首页 > 其它

二分图匹配(KM算法)n^3 分类: ACM TYPE 2014-10-01 21:46 98人阅读 评论(0) 收藏

2014-10-01 21:46 453 查看
#include <iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
const int maxn = 301;
const int INF = (1<<31)-1;
int w[maxn][maxn];
int lx[maxn],ly[maxn]; //顶标

int linky[maxn];

int visx[maxn],visy[maxn];
int slack[maxn];
int n;
bool find(int x)
{
visx[x] = true;
for(int y = 1; y <=n; y++)
{
if(visy[y])   continue;
int t = lx[x] + ly[y] - w[x][y];
if(t==0)
{
visy[y] = true;
if(linky[y] == -1 || find(linky[y]))
{
linky[y] = x;
return true;
}
}
else if(slack[y] > t)      slack[y] = t;
}
return false;
}

int KM()
{
int i,j;

memset(linky,-1,sizeof(linky));
memset(ly,0,sizeof(ly));

for(i = 1; i <=n; i++)			//初始化顶标
{
lx[i] = -INF;
for(j = 1; j <=n; j++)
{
if(w[i][j] > lx[i])   lx[i] = w[i][j];
}
}

for(int x = 1; x <=n; x++)
{
for(i = 1; i <=n; i++) 	slack[i] = INF;
while(true)
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
if(find(x))  break;
int d = INF;

for(i = 1; i <=n; i++)
{
if(!visy[i] && d > slack[i])    d = slack[i];
}
for(i = 1; i <=n; i++)
{
if(visx[i])    lx[i] -= d;
}
for(i = 1; i <=n; i++)
{
if(visy[i])	   ly[i] += d;
else           slack[i] -= d;
}
}
}

int result = 0;
for(i = 1; i <=n; i++)
{
if(linky[i]>-1)
{
result += w[linky[i]][i];
}
}

return result;
}

int main()
{

while(scanf("%d",&n)==1)
{
int cost;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&cost);
w[i][j] = cost;
}
}
printf("%d\n",KM());
}
return 0;
}
更新顶标的问题的了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐