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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值