BZOJ 1116 [POI2008]CLO-Toll 并查集
如果一个连通块是一个树的形态,则不合法,否则合法.
用并查集判断一下即可.
#include <bits/stdc++.h> #define N 100005 #define M 200005 #define setIO(s) freopen(s".in","r",stdin) using namespace std; struct G { int edges; int hd[N],to[M<<1],nex[M<<1]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } }gr,tr; struct Union_Find_set { int p[N],is[N]; void init() { for(int i=0;i<N;++i) p[i]=i; } int find(int x) { return p[x]==x?x:p[x]=find(p[x]); } }ufs; int n,m,flag; int vis[N]; void dfs(int u,int ff) { vis[u]=1; for(int i=gr.hd[u];i;i=gr.nex[i]) { int v=gr.to[i]; if(v==ff) continue; if(!vis[v]) tr.add(u,v),tr.add(v,u),dfs(v, u); else if(vis[v] && flag==0) { tr.add(u, v); tr.add(v,u); flag=1; } } } int main() { int i,j,k; scanf("%d%d",&n,&m); ufs.init(); for(i=1;i<=m;++i) { int a,b; scanf("%d%d",&a,&b); gr.add(a,b); gr.add(b,a); a=ufs.find(a); b=ufs.find(b); if(a!=b) ufs.p[a]=b, ufs.is[b]|=ufs.is[a]; else ufs.is[a]=1; } for(i=1;i<=n;++i) { if(ufs.p[i]==i && !ufs.is[i]) { printf("NIE\n"); return 0; } } printf("TAK\n"); return 0; }