二分图匹配入门专题1M - Cyclic Tour hdu1853km算法--判断自重边
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分图匹配入门专题1M - Cyclic Tour hdu1853km算法--判断自重边相关的知识,希望对你有一定的参考价值。
InputThere are several test cases in the input. You should process to the end of file (EOF).
The first line of each test case contains two integers N (N ≤ 100) and M, indicating the number of cities and the number of roads. The M lines followed, each of them contains three numbers A, B, and C, indicating that there is a road from city A to city B, whose length is C. (1 ≤ A,B ≤ N, A ≠ B, 1 ≤ C ≤ 1000).
OutputOutput one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output -1.
Sample Input
6 9
1 2 5
2 3 5
3 1 10
3 4 12
4 1 8
4 6 11
5 4 7
5 6 9
6 5 4
6 5
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
Sample Output
42
-1
Hint
In the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42.
题意:输入n个顶点m条边,让这些顶点形成环,至少包括两个顶点.输出最小的完备匹配和,如果不存在,输出-1。
思路:把一个点一分为二,就形成了两个集合,求最小匹配,则将权值取负后求最大匹配,最后返回负值。如果图由多个有向环构成,则一定存在完备匹配,如果有权值最大的完备匹配存在,则一定是这个图的最优完备匹配的值,如果有任何一个匹配边是初始化的边权值,说明这个完备匹配不存在。
之前嫌弃题水,现在又写的头疼,今天一天到现在才出了3题,自己真的好菜啊,什么时候能像师父那样厉害就好了,感觉算法真的需要自己理解了才能够应对各种变形,就这道题就超时了
5遍,我怎么知道要判断重边啊~~~
#include<stdio.h>
#include<string.h>
#define N 210
#define INF 0x3f3f3f3f
int map[N][N];
int ans,d;
int w[N][N],lx[N],ly[N];
int linker[N],visx[N],visy[N];
int n,m,nx,ny;
int dfs(int x)
{
int y,tmp;
visx[x] = 1;
for(y = 1; y <= ny; y ++)
{
if(!visy[y])
{
tmp = lx[x] + ly[y] - w[x][y];
if(!tmp)
{
visy[y] = 1;
if(linker[y]==-1||dfs(linker[y]))
{
linker[y] = x;
return 1;
}
}
else if( d > tmp)
d = tmp;
}
}
return 0;
}
int KM()
{
int x,y,i,j,sum;
memset(linker,-1,sizeof(linker));
memset(ly,0,sizeof(ly));
for(x = 1; x <= nx; x ++)
for(y = 1,lx[x] = -INF; y <= ny; y ++)
if(lx[x] < w[x][y])
lx[x] = w[x][y];
for(x = 1; x <= nx; x ++)
{
while(1)
{
d = INF;
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
if(dfs(x))
break;
for(i = 1; i <= nx; i ++)
if(visx[i])
lx[i] -= d;
for(i = 1; i <= ny; i ++)
if(visy[i])
ly[i] += d;
}
}
sum = 0;
for(i = 1; i <= ny; i ++)
{
if(w[linker[i]][i] != -INF)
sum += w[linker[i]][i];
else
return -1;
}
return -sum;
}
int main()
{
int t1,t2,t3;
while(scanf("%d%d",&n,&m)!=EOF)
{
nx = ny = n;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
w[i][j] = -INF;
for(int i = 1; i <= m; i ++)
{
scanf("%d%d%d",&t1,&t2,&t3);
if(-t3 > w[t1][t2])//重复输入取小值
w[t1][t2] = -t3;
}
ans = KM();
printf("%d\n",ans);
}
return 0;
}
以上是关于二分图匹配入门专题1M - Cyclic Tour hdu1853km算法--判断自重边的主要内容,如果未能解决你的问题,请参考以下文章
二分图匹配入门专题1K - Going Home hdu1533km匹配
二分图匹配入门专题1F - COURSES poj1469最大匹配--匈牙利算法模板题
二分图匹配入门专题1D - Matrix hdu2119最小顶点覆盖