hdoj 3435 A new Graph Game 【无向图判断权值最小哈密顿环】【KM算法】
2015-08-25 20:55
453 查看
A new Graph GameTime Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1934 Accepted Submission(s): 827 Problem Description An undirected graph is a graph in which the nodes are connected by undirected arcs. An undirected arc is an edge that has no arrow. Both ends of an undirected arc are equivalent--there is no head or tail. Therefore, we represent an edge in an undirected graph as a set rather than an ordered pair. Now given an undirected graph, you could delete any number of edges as you wish. Then you will get one or more connected sub graph from the original one (Any of them should have more than one vertex). You goal is to make all the connected sub graphs exist the Hamiltonian circuit after the delete operation. What’s more, you want to know the minimum sum of all the weight of the edges on the “Hamiltonian circuit” of all the connected sub graphs (Only one “Hamiltonian circuit” will be calculated in one connected sub graph! That is to say if there exist more than one “Hamiltonian circuit” in one connected sub graph, you could only choose the one in which the sum of weight of these edges is minimum). For example, we may get two possible sums: (1) 7 + 10 + 5 = 22 (2) 7 + 10 + 2 = 19 (There are two “Hamiltonian circuit” in this graph!) Input In the first line there is an integer T, indicates the number of test cases. (T <= 20) In each case, the first line contains two integers n and m, indicates the number of vertices and the number of edges. (1 <= n <=1000, 0 <= m <= 10000) Then m lines, each line contains three integers a,b,c ,indicates that there is one edge between a and b, and the weight of it is c . (1 <= a,b <= n, a is not equal to b in any way, 1 <= c <= 10000) Output Output “Case %d: “first where d is the case number counted from one. Then output “NO” if there is no way to get some connected sub graphs that any of them exists the Hamiltonian circuit after the delete operation. Otherwise, output the minimum sum of weight you may get if you delete the edges in the optimal strategy. Sample Input 3 3 4 1 2 5 2 1 2 2 3 10 3 1 7 3 2 1 2 3 1 2 4 2 2 1 2 3 1 2 4 Sample Output Case 1: 19 Case 2: NO Case 3: 6 HintIn Case 1: You could delete edge between 1 and 2 whose weight is 5. In Case 2: It’s impossible to get some connected sub graphs that any of them exists the Hamiltonian circuit after the delete operation. |
思路:费用流我不会写o(╯□╰)o,TLE到死 。 KM算法直接就过了,无奈了。
气死了!!! 又把做过的费用流用KM刷了一遍。以后碰到这样的题目果断KM,费用流先靠边。
AC代码:2458ms
#include <cstdio> #include <cstring> #include <algorithm> #define INF 0x3f3f3f3f #define MAXN 1010 using namespace std; int lx[MAXN], ly[MAXN]; int Map[MAXN][MAXN]; bool visx[MAXN], visy[MAXN]; int slack[MAXN]; int match[MAXN]; int N, M; void getMap() { for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) Map[i][j] = -INF;//初始化 } int a, b, c; while(M--) { scanf("%d%d%d", &a, &b, &c); if(-c > Map[a][b])//去重 Map[a][b] = Map[b][a] = -c; } } int DFS(int x) { visx[x] = true; for(int y = 1; y <= N; y++) { if(visy[y]) continue; int t = lx[x] + ly[y] - Map[x][y]; if(t == 0) { visy[y] = true; if(match[y] == -1 || DFS(match[y])) { match[y] = x; return 1; } } else if(slack[y] > t) slack[y] = t; } return 0; } int k = 1; void KM() { memset(match, -1, sizeof(match)); memset(ly, 0, sizeof(ly)); for(int x = 1; x <= N; x++) { lx[x] = -INF; for(int y = 1; y <= N; y++) lx[x] = max(lx[x], Map[x][y]); } for(int x = 1; x <= N; x++) { for(int i = 1; i <= N; i++) slack[i] = INF; while(1) { memset(visx, false, sizeof(visx)); memset(visy, false, sizeof(visy)); if(DFS(x)) break; int d = INF; for(int i = 1; i <= N; i++) { if(!visy[i] && slack[i] < d) d = slack[i]; } for(int i = 1; i <= N; i++) { if(visx[i]) lx[i] -= d; } for(int i = 1; i <= N; i++) { if(visy[i]) ly[i] += d; else slack[i] -= d; } } } //判断是否存在完美匹配 int ans = 0; bool flag = true; for(int i = 1; i <= N; i++) { if(match[i] == -1 || Map[match[i]][i] == -INF) { flag = false; break; } ans += Map[match[i]][i]; } printf("Case %d: ", k++); if(flag) printf("%d\n", -ans); else printf("NO\n"); } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &N, &M); getMap(); KM(); } return 0; }
相关文章推荐
- bootstrap-js(六)弹出框
- navicat连接oracle报错ORA-12737: Instant Client Light: unsupported server character set CHS16GBK”
- 时间格式化
- 详细介绍Linux /etc/shadow文件
- DNA序列
- F - 蜘蛛牌(深度搜索)
- Linux内核工程导论——内存管理(三)
- 《C Primer Plus(第五版)中文版》第13章第1至13题
- HDU 2222 — Keywords Search
- 二叉树遍历的应用(路径和问题,判断是否是二叉搜索树,判断是否是二叉平衡树)
- 使用串口AT命令驱动点阵屏 VFD
- 在jdk为1.6或1.7下,eclipse仍然报Remove '@override' annotation错误
- Android-基本控件(Toast 全解)
- Python 爬虫入门《上》
- Jenkins_Maven_Git 持续集成及自动化部署 GentOS版
- 移动WEB开发入门学习笔记
- VMware Workstation(虚拟机)v10.0.1 简体中文破解版
- 几何编程题
- 自增运算
- printf支持的格式