题意描述
给你无向图的NNN个点和MMM条边,保证这 条边都不同且不会存在同一点的自环边,现在问你至少要几笔才能所有边都画一遍。(一笔画的时候笔不离开纸)
解析
无向图中,若一个图是连通的,且奇数度个数的点不超过2个时,必定可以一笔画完
否则一笔可以消灭两个奇数度点,所以笔数为奇数度点个数/2
所以考虑所有连通块即可
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=4e5+100;
const double eps=1e-6;
inline ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return f*x;
}
int n,m;
struct node{int to,nxt,pre;
}p[N*10];
int fi[N],cnt;
inline void addline(int x,int y){p[++cnt]={y,fi[x],-1};fi[x]=cnt;return;
}
bool vis[N];
int ans,du[N];
void init(){memset(fi,-1,sizeof(fi));cnt=-1;memset(vis,0,sizeof(vis));ans=0;memset(du,0,sizeof(du));
}
int o;
void dfs(int x){vis[x]=1;o+=(du[x]&1);for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(!vis[to]) dfs(to);}return;
}
int main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifwhile(scanf("%d%d",&n,&m)!=EOF){init();for(int i=1;i<=m;i++){int x=read(),y=read();addline(x,y);addline(y,x);++du[x];++du[y];}for(int i=1;i<=n;i++){if(!vis[i]&&du[i]){o=0;dfs(i);if(o==0||o==2) ans++;else ans+=o/2;}}printf("%d\n",ans);}return 0;
}