题意:给出一个图,问几笔画才能经过所有边
思路:对于一个连通图而言,有这样的一个性质:其需要画的笔数=度数为奇数的点数除以2,那么由于给出的图并没有说明是否是连通图,我们需要用并查集来维护连通图,并且忽略单点的“子图”
#include<bits/stdc++.h>
#define fi first
#define se second
#define FOR(a) for(int i=0;i<a;i++)
#define sc(a) scanf("%d",&a)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 1e5+10;
const ll mod = 1000000007;
const int base=131;
map<string, int>ml;
int de[N],n,m,t,k,flag,f[N],cnt;
int vis[N];
vector<int> v[N];
priority_queue<int> q;
int fid(int x)
{
if(f[x]==x) return x;
else return f[x]=fid(f[x]);
}
void join (int x,int y)
{
int fx=fid(x),fy=fid(y);
if(fx!=fy)
{
f[fx]=fy;
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int ans=0,sum=0;
for(int i=1;i<=n;i++)
{
f[i]=i;
de[i]=0;
vis[i]=0;
}
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
de[x]++;
de[y]++;
join(x,y);
}
for(int i=1;i<=n;i++)
{
if(de[i]&1)
{
sum++;
vis[fid(i)]=1;
}
}
ans+=sum/2;
for(int i=1;i<=n;i++)
{
if(de[i])
{
if(vis[fid(i)]==0)
{
ans++;
vis[fid(i)]=1;
}
}
}
cout<<ans<<endl;
}
}