这个题目刚开始思路有误,以为是考察图的最大连通数,其实并不是,题目考察的是欧拉回路的判断。大体思路如下:首先按照题意读取每条边的顶点,建立顶点与顶点之间的联系,然后对于每个读取的和边相关的顶点,判断顶点是否被访问过,如果没有就从该顶点开始进行dfs遍历,同时在dfs的过程当中要判断每个顶点是否为奇点(也就是和顶点相连接的边的个数为奇数,如果是,那么就记数加1)。然后判断该子图中的奇数个数,如果为0或者为2,则不需要添加额外的边,否则需要添加的边的数量为:奇点个数/2-1.同时需要注意,通过输入的待检测的边组成的连通子图之间也要加上一条边进行连接。具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;
int V, E, T;
int amount;
void dfs(int ind,map<int,vector<int>>& area,vector<bool>& visit){
visit[ind] = true;
if (area[ind].size() & 1) amount++;
for (int i : area[ind]){
if (!visit[i]) dfs(i, area, visit);
}
}
int main(){
int Case = 0;
while (cin >> V >> E >> T){
Case++;
if (V + E + T == 0) break;
map<int,vector<int>> area;
for (int i = 0; i < E; i++){
int a, b;
cin >> a >> b;
area[a].push_back(b);
area[b].push_back(a);
}
vector<bool> visit(V+1,false);
int res = 0;
for (auto it:area){
if (!visit[it.first]){
amount = 0;
dfs(it.first,area,visit);
if (amount == 0) res += 1;
else res += amount / 2;
}
}
if (res > 0) res -= 1;
cout << "Case " << Case << ": " << (res + E)*T << endl;
}
return 0;
}