并查集模板
int finds(int x)
{
return fa[x]==x?x:fa[x]=finds(fa[x]);
}
bool bing(int x,int y)
{
int fx=finds(x);
int fy=finds(y);
if(fx==fy) return 0;
fa[fy]=fx;
return 1;
}
经典:http://poj.org/problem?id=2236
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int N=1e3+10;
struct node{
int x,y;
}f[N];
int t,n,m,d;
int fa[N],mp[N][N];
bool vis[N];
int calc(node x,node y)
{
return (x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y);
}
int finds(int x)
{
return fa[x]==x?x:fa[x]=finds(fa[x]);
}
void bing(int x,int y)
{
x=finds(x);
y=finds(y);
if(x!=y) fa[x]=y;
}
int main()
{
int x,y;
memset(mp,0,sizeof mp);
memset(vis,0,sizeof vis);
for(int i=0;i<N;i++) fa[i]=i;
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&f[i].x,&f[i].y);
for(int j=1;j<i;j++)
if(calc(f[i],f[j])<=d*d)
mp[i][j]=mp[j][i]=1;
}
char ch;
while(cin>>ch)
{
if(ch=='O')
{
scanf("%d",&x);
vis[x]=1;
for(int i=1;i<=n;i++)
if(i!=x&&mp[x][i]&&vis[i]) bing(x,i);
}
else
{
scanf("%d%d",&x,&y);
if(finds(x)==finds(y)) printf("SUCCESS\n");
else printf("FAIL\n");
}
}
return 0;
}
种类并查集:http://poj.org/problem?id=1182
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int N=200000+10;
int fa[N],sum[N];
int finds(int x)
{
if(fa[x]!=x)
{
int y=fa[x];
fa[x]=finds(fa[x]);
sum[x]+=sum[y];
}
return fa[x];
}
bool bing(int x,int y,int d)
{
int fx=finds(x);
int fy=finds(y);
if(fx==fy) return sum[y]!=sum[x]+d;
fa[fy]=fx;
sum[fy]=sum[x]-sum[y]+d;
return 0;
}
int main()
{
int t,n,m,x,y,d,tt=0;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<N;i++) fa[i]=i,sum[i]=0;
int ans=0;
while(m--)
{
scanf("%d%d%d",&x,&y,&d);
if(bing(x-1,y,d)) ans++;
}
printf("%d\n",ans);
}
return 0;
}
带权并查集http://acm.hdu.edu.cn/showproblem.php?pid=3038
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int N=200000+10;
int fa[N],sum[N];
int finds(int x)
{
if(fa[x]!=x)
{
int y=fa[x];
fa[x]=finds(fa[x]);
sum[x]+=sum[y];
}
return fa[x];
}
bool bing(int x,int y,int d)
{
int fx=finds(x);
int fy=finds(y);
if(fx==fy) return sum[y]!=sum[x]+d;
fa[fy]=fx;
sum[fy]=sum[x]-sum[y]+d;
return 0;
}
int main()
{
int t,n,m,x,y,d,tt=0;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<N;i++) fa[i]=i,sum[i]=0;
int ans=0;
while(m--)
{
scanf("%d%d%d",&x,&y,&d);
if(bing(x-1,y,d)) ans++;
}
printf("%d\n",ans);
}
return 0;
}
逆向并查集http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
const int N=10010;
int pre[N+10];
int sum[N+10];//最大值
int val[N+10];//下标
int a[N+10];
int ans[N*10];
struct node{
int x,y;
};
node num[N*10];
node destory[N*10];
map<int,int>mp[N];
int use[N*2];
void init()
{
for(int i=0;i<N;i++)
pre[i]=i;
memset(use,0,sizeof use);
}
int Find(int x)
{
if(pre[x]!=x)
pre[x]=Find(pre[x]);
return pre[x];
}
int Union(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
pre[fx]=fy;
if(sum[fx]>sum[fy])
{
sum[fy]=sum[fx];
val[fy]=val[fx];//下标
}else if(sum[fx]==sum[fy] && val[fy]>val[fx])
val[fy]=val[fx];
}
}
int main()
{
int n,m;
int i,j,k;
int x,y,w,t;
int cnt,q;
char str[20];
t=0;
while(~scanf("%d",&n))
{
if(t==1) puts("");
else t=1;
init();
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
mp[i].clear();
sum[i]=a[i];
val[i]=i;
}
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
if(x>y) swap(x,y);
num[i].x=x;
num[i].y=y;
mp[x][y]=i;
}
scanf("%d",&q);
for(j=0;j<q;j++)
{
scanf("%s",str);
if(str[0]=='q')
{
scanf("%d",&x);
destory[j].x=x;
destory[j].y=-1;
}else{
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
int tmp=mp[x][y];
use[tmp]=1;
destory[j].x=x;
destory[j].y=y;
}
}
for(i=0;i<m;i++)
if(!use[i])
Union(num[i].x,num[i].y);
cnt=0;
for(i=q-1;i>=0;i--)
{
if(destory[i].y==-1)
{
x=destory[i].x;
int t1=Find(x);
if(sum[t1]>a[x]) ans[cnt++]=val[t1];
else ans[cnt++]=-1;
}else{
Union(destory[i].x,destory[i].y);
}
}
for(i=cnt-1;i>=0;i--)
printf("%d\n",ans[i]);
}
return 0;
}
枚举+并查集 http://poj.org/problem?id=2912
/*
POJ 2912
枚举+并查集
枚举每一个裁判,看有没有不出错的
如果没有,说明是Impossible
如果有超过一个,那么就是Can not determine
如果只有一个,那么输出其他出错的位置的最大值
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN=510;
const int MAXM=2010;
struct Node
{
int u,v;
int re;
}node[MAXM];
int F[MAXN];
int val[MAXN];
int find(int x)
{
if(F[x]==-1)return x;
int tmp=find(F[x]);
val[x]+=val[F[x]];
val[x]%=3;
return F[x]=tmp;
}
char str[30];
int main()
{
int n,m;
int u,v;
while(scanf("%d%d",&n,&m)==2)
{
gets(str);
for(int i=0;i<m;i++)
{
//scanf("%s",&str);
gets(str);
int t=0;
int len=strlen(str);
for(t=0;t<len;t++)
if(str[t]=='>'||str[t]=='='||str[t]=='<')
break;
u=0;
for(int j=0;j<t;j++)
{
u*=10;
u+=str[j]-'0';
}
v=0;
for(int j=t+1;j<len;j++)
{
v*=10;
v+=str[j]-'0';
}
node[i].u=u;
node[i].v=v;
if(str[t]=='=')node[i].re=0;
else if(str[t]=='<')node[i].re=1;
else node[i].re=2;
}
int ansi;
int anst=0;
int t0=0;//不矛盾的个数
for(int i=0;i<n;i++)
{
memset(F,-1,sizeof(F));
memset(val,0,sizeof(val));
int ff=-1;
for(int j=0;j<m;j++)
{
if(node[j].u==i || node[j].v==i)continue;
u=node[j].u;
v=node[j].v;
int t1=find(u);
int t2=find(v);
if(t1==t2)
{
if(val[v]!=(val[u]+node[j].re)%3)
{
ff=j+1;
break;
}
}
else
{
F[t2]=t1;
val[t2]=val[u]-val[v]+node[j].re;
val[t2]=(val[t2]+3)%3;
}
}
if(ff==-1)
{
ansi=i;
t0++;
}
else anst=max(anst,ff);
}
if(t0==0)printf("Impossible\n");
else if(t0>=2)printf("Can not determine\n");
else
printf("Player %d can be determined to be the judge after %d lines\n",ansi,anst);
}
return 0;
}