这道题题意比较好理解,但需要一些关于欧拉道路的思考。
刚开始考虑用并查集做,每个集(或者说每条链)有可能是环状,或者有多个奇点,这就需要多个入口和出口,需要统计,用并查集并不太好实现。然后考虑DFS的做法,需要计算每个节点的度数,统计每条链的奇点个数,并且注意每条连至少需要一个入口和一个出口,最后将多条链合并即可。
#include <bits/stdc++.h> using namespace std; int v, e, t, kase = 0; const int maxn = 1024; vector<int> Road[maxn]; bool vis[maxn]; void init() { memset(vis, false, sizeof(vis)); for(int i = 0; i < maxn; ++i) Road[i].clear(); } int DFS(int n) { if(vis[n]) return 0; int cnt = 0; vis[n] = true; cnt += (Road[n].size() & 1); for(size_t 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); } int main() { //freopen("in.txt", "r", stdin); ios::sync_with_stdio(false); while(init(), cin >> v >> e >> t, v || e || t){ for(int i = 0; i < e; i++){ int x, y; cin >> x >> y; Road[x].push_back(y); Road[y].push_back(x); } printf("Case %d: %d ", ++kase, solve()); } return 0; }