输入输出样例
输入 #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;
}