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 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 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 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 Hint In 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. |
题意:给你一个N个点M条无向边的图。问你存不存在哈密顿环,若不存在输出NO,反之输出 权值之和最小的哈密顿环。
思路:费用流我不会写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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。