UVa 12118 检查员的难题 (dfs判连通, 构造欧拉通路)

题意:

分析:

欧拉通路:图连通;图中只有0个或2个度为奇数的结点

这题我们只需要判断选择的边构成多少个联通块, 再记录全部联通块一共有多少个奇度顶点。

然后我们在联通块中连线, 每次连接两个联通块就减少2个奇度顶点, 然后再数一下剩下的奇度顶点odd(肯定是剩下偶数个), 因为存在两个奇度顶点的图也是欧拉通路, 我们只需要在(odd - 2)个顶点中连线使其变为偶度顶点即可。

如果本身就没有奇度顶点就不需要除了。

所以答案就是 T * (E  +(联通块 - 1) + (odd - 2)/ 2))

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1007;
 4 int V, E, T;
 5 vector<int> G[maxn];
 6 set<int> pick;
 7 int deg[maxn];
 8 bool vis[maxn];
 9 void dfs(int u){
10     vis[u] = 1;
11     for(int i = 0; i < G[u].size(); i++){
12         if(!vis[G[u][i]]){
13             dfs(G[u][i]);
14         }
15     }
16 }
17 int main(){
18 
19     int kase = 1;
20     while(scanf("%d %d %d", &V, &E, &T) && V){
21 
22         memset(deg,0, sizeof(deg));
23         memset(vis,0 , sizeof(vis));
24         pick.clear();
25 
26         for(int i = 0; i < E; i++){
27             int u, v;
28 
29             scanf("%d %d", &u, &v);
30             deg[u]++, deg[v]++;
31             G[u].push_back(v);
32             G[v].push_back(u);
33             pick.insert(v);
34             pick.insert(u);
35         }
36 
37         int part = 0;
38         int odd = 0, even = 0;
39         for(auto it = pick.begin(); it != pick.end(); it++){
40             if(!vis[*it]){
41                 dfs(*it);
42                 part++;
43             }
44             if(deg[*it] % 2 == 0){
45                 even++;
46             }
47             else odd++;
48             G[*it].clear();
49         }
50         odd -= (part - 1) * 2;
51         
52         int ans = E + part - 1;
53         
54         if(odd > 2){
55                 ans += (odd -1)/2;
56         }
57         
58         if(E == 0) ans = 0;//特判一下没有边的情况
59         printf("Case %d: %d
",kase++, ans * T);
60 
61     }
62     return 0;
63 }
原文地址:https://www.cnblogs.com/Jadon97/p/7458862.html