第二十七题 UVA12118 检查员的难题 Inspector's Dilemma

PDF

输入输出样例
输入 #1复制
5 3 1
1 2
1 3
4 5
4 4 1
1 2
1 4
2 3
3 4
0 0 0
输出 #1复制
Case 1: 4
Case 2: 4

洛谷上给出的难度是普及 普及难度的题我都不会 心塞```````````

我本来以为是啥 并查集或者说Tarjan,,,,,然后想了想不对,

题解: 转载

首先想一想,要是所有的边都没有公共节点该多好。那么答案就是(E-1)*T了。
可惜并不是这样,那么,我们就可以把几个有公共端点的边看成一个子图。对于一个子图,它要有一条边连接进来,再有一条边连出去(入口出口除外)。
所以就想到一个方法,对于一个子图,我们要在原图中加几条边使它联通,再把他们穿起来。想到了什么?欧拉道路!对于一个子图,我们把它变成一个”一笔画”图,添加的边数加上E,再加上连接各个子图的路径就是答案!

————————————————
版权声明:本文为CSDN博主「K_rew」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/k_rew/article/details/50270307

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 1002;
vector<int> G[maxn];
int vis[maxn],V,E,T;

int DFS(int u) {
	int Num = 0;
	vis[u] = 0;
	int n = G[u].size();
	if(n % 2) ++Num;
	for(int i=0; i<n; i++) {
		if(vis[G[u][i]]) Num += DFS(G[u][i]);
	}
	return Num;
}

int Solve() {
	int Ans = 0;
	for(int i=1; i<=V; i++) 
		if(vis[i]) Ans += (DFS(i) - 1) / 2 + 1;
	return max(Ans - 1,0);
}

int main(int argc,char* argv[]) {
	int kase = 0;
	while(scanf("%d%d%d",&V,&E,&T) == 3 && V != 0) {
		int Ans = 0;
		for(int i=1; i<=V; i++) G[i].clear();
		memset(vis,0,sizeof(vis));
		for(int u,v,i=1; i<=E; i++) {
			scanf("%d %d",&u,&v);
			G[u].push_back(v);
			G[v].push_back(u);
			vis[u] = vis[v] = 1;
			++Ans;
		}
		
		printf("Case %d: %d\n",++kase,T*(Ans + Solve()));
		
	}
	
	
	return 0;
}
发布了732 篇原创文章 · 获赞 31 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_35776409/article/details/103933680
今日推荐