UVa 12118 检查员的难题(dfs+欧拉回路)

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 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6240824.html