题目链接如下:
脑雾严重,这道题一开始我想的方向有问题.....后来看了别人的题解才写出来的.....
用的是欧拉路径的充要条件;以及数连通块。需要加的高速路数目 = 连通块个数 - 1 + sum(每个连通块中连成欧拉路径需要加的高速路数目)。
cpp
#include <cstdio>
#include <algorithm>
// #define debug
int V, E, T, a, b, tot, odd, kase = 0;
int arc[1001][1001];
bool vis[1001];
int cnt[1001];
void dfs(int k){
vis[k] = true;
if (cnt[k] % 2){
odd++;
}
for (int i = 1; i <= V; ++i){
if (!vis[i] && arc[i][k]){
dfs(i);
}
}
}
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
while (scanf("%d %d %d", &V, &E, &T) == 3 && (V || E || T)){
std::fill(vis, vis + V + 1, true);
std::fill(cnt, cnt + V + 1, 0);
tot = E - 1;
for (int i = 0; i <= V; ++i){
for (int j = 0; j <= V; ++j){
arc[i][j] = arc[j][i] = 0;
}
}
for (int i = 0; i < E; ++i){
scanf("%d %d", &a, &b);
arc[a][b] = arc[b][a] = 1;
vis[a] = vis[b] = false;
cnt[a]++;
cnt[b]++;
}
for (int i = 1; i <= V; ++i){
if (!vis[i]){
odd = 0;
dfs(i);
if (odd > 2){
tot += (odd - 2) / 2;
}
tot++;
}
}
printf("Case %d: %d\n", ++kase, E == 0 ? 0 : tot * T);
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}