码迷,mamicode.com
首页 > 其他好文 > 详细

习题6-14 检查员的难题 UVa12118

时间:2015-04-02 09:10:30      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:dfs   欧拉回路   

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;
}

习题6-14 检查员的难题 UVa12118

标签:dfs   欧拉回路   

原文地址:http://blog.csdn.net/u014800748/article/details/44817901

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!