传送门
题解:
对于一般的无向连通图,如果有x个点入度为奇数,覆盖所有边所需要的笔数是max(x/2,1),严格证明戳这儿。可以理解为用x/2笔消掉多出来的边,取1的时候图是一个欧拉图。
P.S.注意特判
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=1e5+2;
int n,m;
int deg[MAXN],fa[MAXN],odd[MAXN],sum[MAXN],ans;
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
inline int find(int x) {
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main() {
while (~scanf("%d%d",&n,&m)) {
memset(sum,0,sizeof(sum));
memset(odd,0,sizeof(odd));
memset(deg,0,sizeof(deg));
for (register int i=1;i<=n;++i) fa[i]=i;
for (register int i=0;i<m;++i) {
int u=read(),v=read();
++deg[u],++deg[v];
u=find(u),v=find(v);
if (u^v) fa[u]=v;
}
for (register int i=1;i<=n;++i) {
++sum[find(i)];
if (deg[i]%2) ++odd[fa[i]];
}
ans=0;
for (register int i=1;i<=n;++i) {
if (!sum[i]&&!odd[i]) continue;
if (sum[i]==1) continue;//只有一个点的连通块
ans+=max(1,odd[i]>>1);
}
printf("%d\n",ans);
}
return 0;
}