- 在完全图中找一条欧拉道路,使之经过选中的边且距离最小。
- 等价于将图中各个连通块连接,且使得每个子连通块存在欧拉道路。
- 欧拉道路:存在欧拉道路当且仅当度为奇数的点的个数小于等于2且连通。
- 这里用的并查集维护。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1005;
int V,E,T,u,v,f[maxn],in[maxn],vcnt,cnt[maxn],ans[maxn],ans0,cas;
bool vis[maxn];
int finds(int x){
return x==f[x]?x:f[x]=finds(f[x]);
}
void merges(int x,int y)
{
x=finds(x);
y=finds(y);
f[x]=y;
}
int main()
{
while(cin>>V>>E>>T&&V)
{
cas++;
vcnt = ans0 = 0;
memset(vis,0,sizeof(vis));
memset(in,0,sizeof(in));
memset(f,0,sizeof(f));
memset(ans,0,sizeof(ans));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=V;i++)
f[i] = i;
for(int i=1;i<=E;i++)
{
cin>>u>>v;
vis[u]=vis[v]=1;
in[u]++;in[v]++;
merges(u,v);
}
for(int i=1;i<=V;i++)
{
if(vis[i])
{
if(!cnt[finds(i)])
cnt[finds(i)]=++vcnt;
if(in[i]%2)
ans[cnt[finds(i)]]++;
}
}
for(int i=1;i<=vcnt;i++)
ans0+=ans[i]>2?(ans[i]-2)/2:0;
printf("Case %d: %d\n",cas,(E+ans0+max(0,vcnt-1))*T);
}
return 0;
}