BZOJ 4238: 电压 DFS树
分类讨论一下奇环和偶环的情况.
code:
#include <bits/stdc++.h> #define N 200006 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int edges=1; int hd[N],to[N<<1],nex[N<<1],dep[N],ev[N],od[N],fa[N<<1],vis[N<<1],gg[N],OD,EV; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs(int u,int ff) { gg[u]=1; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(vis[i]) continue; vis[i]=vis[i^1]=1; if(!gg[v]) { dep[v]=dep[u]+1; fa[v]=i; dfs(v,u); od[u]+=od[v]; ev[u]+=ev[v]; } else { if(dep[v]>dep[u]) continue; if((dep[u]-dep[v])%2==0) { // 奇环 od[u]++; od[v]--; ++OD; } else { ev[u]++; ev[v]--; ++EV; } } } } int main() { // setIO("input"); int i,j,n,m; scanf("%d%d",&n,&m); for(i=1;i<=m;++i) { int x,y; scanf("%d%d",&x,&y); add(x,y),add(y,x); } for(i=1;i<=n;++i) if(!gg[i]) dfs(i,0); int ans=0; for(i=1;i<=n;++i) if(od[i]==OD&&ev[i]==0&&fa[i]) ++ans; if(OD==1) ++ans; printf("%d\n",ans); return 0; }