您的位置:首页 > 其它

最佳完美匹配性质2 uva11383-点上的性质

2017-08-14 13:45 225 查看
//此题我觉得应该是阔以求row(i)+col(j)的最大值的只不过是在w(i,j)>=row(i)+row(j)的情况下,将边反号就好了,当然也阔以不反号直接求。。上一篇题解写了。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int map[600][600];
int visitx[600], visity[600], match[600], valuex[600], valuey[600],slack[600];
int n;
bool dfs(int num)
{
visitx[num] = 1;
for (int i = 0; i < n; i++)
{
if (visity[i])continue;
int t = valuex[num] + valuey[i] - map[num][i];
if (t == 0)
{
visity[i] = 1;
if (match[i] == -1 || dfs(match[i]))
{
match[i] = num;
return true;
}
}
else
{
slack[i] = min(slack[i], t);
}
}
return false;
}
void km()
{
for (int i = 0; i < n; i++)match[i] = -1;
for (int i = 0; i < n; i++)
{
for (int k = 0; k < n; k++)slack[k] = 1000000000;
while (1)
{
for (int k = 0; k < n; k++)visitx[k] = 0, visity[k] = 0;
if (dfs(i))break;
int d = 1000000000;
for (int k = 0; k < n; k++)
if (!visity[k])d = min(d, slack[k]);
for (int k = 0; k < n; k++)
{
if (visitx[k])
valuex[k] -= d;
if (visity[k])
valuey[k] += d;
else
slack[k] -= d;
}
}
}
}
int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = 0; i < n; i++)
{
valuex[i] = -1; valuey[i] = 0;
for (int j = 0; j < n; j++)
{
scanf("%d", &map[i][j]);
valuex[i] = max(valuex[i], map[i][j]);
}
}
km();
long long ans = 0;
for (int i = 0; i < n; i++)
{
if (i != n - 1)
printf("%d ", valuex[i]);
else
printf("%d", valuex[i]);
ans += valuex[i];
}
printf("\n");
for (int i = 0; i < n; i++)
{
if (i != n - 1)
printf("%d ", valuey[i]);
else
printf("%d", valuey[i]);
ans += valuey[i];
}
printf("\n");
printf("%d\n", ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: