题意:每条边过且只过一次,问至少要画几笔才能全部边都经过,孤立的点忽视。
解:
先用并查集把在一个连通图上的顶点并在一起。
对于每个联通图,度为奇数点个数为sum,那么需要sum/2笔画。然后把这个连通图标记。
其他连通图所有点的度为偶数,只需一笔画。标记此连通图。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <string.h>
#include <map>
#include <set>
using namespace std;
#define MAXN 100005
#define LL long long
int fa[MAXN],vis[MAXN];
int n,m;
int du[MAXN];
int ans[MAXN];
int findfa(int x)
{
if(x==fa[x])return x;
return fa[x]=findfa(fa[x]);
}
int main()
{
int i;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
{
fa[i]=i;
du[i]=0;
ans[i]=0;
vis[i]=0;
}
for(i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
du[u]++;
du[v]++;
int tx=findfa(u);
int ty=findfa(v);
if(tx!=ty)
{
fa[tx]=ty;
}
}
for(i=1;i<=n;i++)
{
if(du[i]==0)
vis[i]=1;//把单个点标记
}
int sum=0;
for(i=1;i<=n;i++)
{
int f=findfa(i);
if(vis[f]==1)continue;
if(du[i]%2)
{
sum++;//记录度为奇数的点
}
}
sum=sum/2;//这些点需要sum/2笔画(无向图)
for(i=1;i<=n;i++)
{
int f=findfa(i);
if(vis[f]==1)
continue;
else
{
if(du[i]%2)
vis[f]=1;//标记这些度为奇数的连通图
}
}
for(i=1;i<=n;i++)//再找度为偶数的连通图
{
int f=findfa(i);
if(vis[f]==1)
continue;
if(du[i]%2==0)
{
vis[f]=1;//找到一个就把这个连通图标记
sum++;
}
}
printf("%d\n",sum);
}
return 0;
}