标签:
链接:http://acm.hust.edu.cn/vjudge/problem/38518
分析:无向图计算欧拉路径。注意:构造的对象是欧拉路径,不是回路!条件:起终点度数为奇数,其它点的度数为偶数。有x个联通块,每个联通块形成链,在每个联通块上跑dfs求出奇点数,由于是链所以至少为2,最后将所有联通块的链合并,将多算的起点和终点减去2,然后一条边能消去两个奇点,所以需要额外添加的边数为(总奇点数—2)/2,因为E可以取0所以最后还要和0取max。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 1000 + 5; 8 9 int V, E, T, vis[maxn]; 10 vector<int> roads[maxn]; 11 12 int dfs(int u) { 13 if (vis[u]) return 0; 14 vis[u] = 1; 15 int odd_cnt = 0; 16 odd_cnt += (roads[u].size() & 1); 17 for (int i = 0; i < roads[u].size(); i++) 18 odd_cnt += dfs(roads[u][i]); 19 return odd_cnt; 20 } 21 22 int solve() { 23 int ans = 0; 24 for (int i = 1; i <= V; i++) 25 if (!vis[i] && !roads[i].empty()) 26 ans += max(dfs(i), 2); 27 return T * ((ans - 2) / 2 + E); 28 } 29 30 int main() { 31 int kase = 0; 32 while (scanf("%d%d%d", &V, &E, &T) == 3 && (V || E || T)) { 33 for (int i = 1; i <= V; i++) roads[i].clear(); 34 memset(vis, 0, sizeof(vis)); 35 for (int i = 0; i < E; i++) { 36 int u, v; scanf("%d%d", &u, &v); 37 roads[u].push_back(v), roads[v].push_back(u); 38 } 39 printf("Case %d: %d\n", ++kase, solve()); 40 } 41 return 0; 42 }
UVa12118 Inspector's Dilemma (欧拉路径)
标签:
原文地址:http://www.cnblogs.com/XieWeida/p/5837705.html