【二分图匹配入门专题1】M
来源:互联网 发布:建立党建工作网络平台 编辑:程序博客网 时间:2024/06/06 04:54
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 91 2 52 3 53 1 103 4 124 1 84 6 115 4 75 6 96 5 46 51 2 12 3 13 4 14 5 15 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 0x3f3f3f3fint 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;}
- 【二分图匹配入门专题1】M
- 【二分图匹配入门专题1】A
- 【二分图匹配入门专题1】B
- 【二分图匹配入门专题1】C
- 【二分图匹配入门专题1】D
- 【二分图匹配入门专题1】F
- 【二分图匹配入门专题1】E
- 【二分图匹配入门专题1】H
- 【二分图匹配入门专题1】I
- 【二分图匹配入门专题1】K
- 【二分图匹配入门专题1】L
- 【二分图匹配入门专题1】 N
- 【二分图匹配入门专题1】O
- 【二分匹配入门专题1】G
- 【二分匹配入门专题1】J
- 【二分匹配入门专题1】P
- 专题:二分图匹配
- 【二分图匹配入门专题1】poj3686 【km+思维建图】
- poj 3625 Building Roads (prim)
- secureCRT如何通过SSH2连上ubuntu
- Atlassian系列软件破解研究记录
- 常用框架
- IO流学习小结
- 【二分图匹配入门专题1】M
- noip2013货车运输(lca)
- 杭电 OJ 1720 A+B Coming
- EtherCAT State Transition
- lower_bound()返回值
- STM8S105系列单片机管脚复用配置(选项字节的配置)
- 交叉排序
- HDU-Kirinriki
- JavaScript Canvas 绘图