1.题目描述:点击打开链接
2.解题思路:本题利用DFS和欧拉道路解决。本题其实要求找一些路径,使得和要求经过的那些路径能够组成欧拉道路(注意不是欧拉回路,“欧拉道路”是指除了起点和终点外,路径上的其他点的入度等于出度的道路)。首先用dfs来判断连通性,这里用dfs还有另外一个原因就是要统计度数为奇数的点的个数,因为这样的点都需要额外添加一条道路使其度数变为偶数,符合欧拉道路的要求。由于添加一条路径后会使得两个端点的度数同时变为2,而且起点和终点的度数均要为奇数,所以统计完后还要减去2,因此最后的路径总数是E+(res-2)/2。其中(res-2)/2就是最后又添加上的路径数目。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define N 1000+10 int V, E, T; vector<int>Road[N]; int vis[N]; void init() { memset(vis, 0, sizeof(vis)); for (int i = 0; i < N; i++) Road[i].clear(); } int dfs(int n) { if (vis[n])return 0; int cnt = 0; vis[n] = 1; cnt += (Road[n].size() & 1);//统计度数为奇数的点 for (int i = 0; i < Road[n].size(); i++) cnt += dfs(Road[n][i]); return cnt; } int solve() { int res = 0; for (int i = 1; i <= V;i++) if (!vis[i] && !Road[i].empty())//注意一定要防止重复累加! res += max(dfs(i), 2);//统计所有度数为奇数的点的个数 return T*(max((res - 2) / 2, 0) + E);//最终的答案是E加上新增加的路径数目(res-2)/2 } int main() { //freopen("t.txt", "r", stdin); int rnd = 0; while (init(), cin >> V >> E >> T, V || E || T) { int x, y; for (int i = 0; i < E; i++) { scanf("%d%d", &x, &y); Road[x].push_back(y); Road[y].push_back(x); } printf("Case %d: %d\n", ++rnd, solve()); } return 0; }
原文地址:http://blog.csdn.net/u014800748/article/details/44817901