https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3270
2017年的第一题。
题意:给出必须要经过的边,找一条经过所有边的最短道路。
一开始一点想法都没有,后来网上看了下才明白是要用dfs和欧拉回路来做的。
欧拉回路是这样说的:如果一个无向图是连通的,且最多只有两个奇点,则一定存在欧拉道路。如果有两个奇点,则必须从其中一个奇点出发,另一个奇点终止;如果奇点不存在,则可以从任意点出发,最终一定会回到该点。
对于这道题,用dfs可以求出连通块来,由于是要形成欧拉道路就可以了,所以可以存在两个奇点,但是如果超过了两个奇点,那么每个奇点就得多加一条边使之成为偶数点,最终只剩下两个奇点,那么就可以形成欧拉道路了。
这道题我错了好久,在输入的时候我是这么写的while (cin >> v >> e >> t && v && e && t ),但其实只要while (cin >> v >> e >> t && v )就可以了。
通过这道题,终于好好的了解了下欧拉回路。
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 using namespace std; 5 6 const int maxn = 1500; 7 8 int G[maxn][maxn]; 9 int v; 10 int degree[maxn]; 11 int ans; 12 13 void dfs(int u) 14 { 15 for (int i = 1; i <= v; i++) 16 { 17 if (G[u][i]) 18 { 19 degree[u]++; //统计每个结点的度数 20 degree[i]++; 21 G[u][i] = G[i][u] = 0; 22 ans++; 23 dfs(i); 24 } 25 } 26 } 27 28 int main() 29 { 30 int e, t; 31 int x, y; 32 int kase = 0; 33 while (cin >> v >> e >> t && v ) 34 { 35 memset(G, 0, sizeof(G)); 36 for (int i = 0; i < e; i++) 37 { 38 cin >> x >> y; 39 G[x][y] = 1; 40 G[y][x] = 1; 41 } 42 int count = 0; 43 ans = 0; 44 for (int i = 1; i <= v; i++) 45 { 46 for (int j = 1; j <= v; j++) 47 { 48 if (G[i][j]) 49 { 50 memset(degree, 0, sizeof(degree)); 51 count++; //统计连通块 52 dfs(i); 53 int jidian = 0; //计算出奇点的个数 54 for (int i = 1; i <= v; i++) 55 { 56 if (degree[i] % 2 == 1) jidian++; 57 } 58 if (jidian > 2) ans += (jidian - 2)/2; 59 } 60 } 61 } 62 ans = ans + count; 63 if (ans) ans = ans - 1; 64 cout<<"Case "<<++kase<<": "<<ans*t<<endl; 65 } 66 return 0; 67 }
原文:http://www.cnblogs.com/zyb993963526/p/6240824.html