题解
先判断有多少个连通块,假设有k个,就需要k-1条路将它们连起来,(特判一个的情况),还要计算每个连通块中的度为奇数的点,假设有n个这样的点,就要填(n-1)/2条边让它形成欧拉路,这样是最短的情况。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <vector>
using namespace std;
int vis[1005],du[1005];
vector<int> v[1005];
int cnt,sum;
void dfs(int x)
{
vis[x] = 1;
if(du[x] % 2) sum++;
for(int i = 0 ; i < v[x].size();i++){
if(!vis[v[x][i]]){
dfs(v[x][i]);
}
}
}
int main()
{
int n,m,V,t = 1;
while(cin >> n >> m >> V && n+m+V){
memset(vis,0,sizeof vis);
memset(du,0,sizeof du);
int a,b;
for(int i = 0 ; i < m ; i++){
scanf("%d %d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
du[a]++;
du[b]++;
}
cnt = 0;
int ans = m;
for(int i = 0 ; i < n ; i++){
if(!vis[i] && v[i].size()){
sum = 0; //奇度点的个数
dfs(i);
cnt++; //连通块的数目
ans += (sum -1) /2; //变成欧拉路应添加的最少边
}
}
if(cnt > 1) ans += cnt-1; //将连通块连接起来
printf("Case %d: %d\n",t++,ans*V);
}
return 0;
}