kuangbin 并查集题单 代码

题单链接
https://vjudge.net/article/752

1. POJ-2236 Wireless Network

//https://vjudge.net/problem/POJ-2236
#include <cstdio>
#define N 1005

int f[N];
bool broken[N];
int n,d,D,p,q;
char Q[3];
int X[N],Y[N];

int Fa (int x)
{
    
    
	return f[x]==x ? x : f[x]=Fa(f[x]);
}

inline int fail(int u,int v)
{
    
    
	return (X[u]-X[v])*(X[u]-X[v])+(Y[u]-Y[v])*(Y[u]-Y[v])>D;
}

int main()
{
    
    
	
	scanf("%d%d",&n,&d);
	D=d*d;
	for (int i=1; i<=n; i++) {
    
    
		broken[i]=1;
		f[i]=i;
		scanf("%d%d",&X[i],&Y[i]);
	}
	
	while (scanf("%s",Q)!=EOF) {
    
    
		if (Q[0]=='O') {
    
    
			scanf("%d",&p);
			for (int i=1; i<=n; i++) {
    
    
				if (i!=p && !broken[i] && !fail(p,i)) {
    
    
					f[Fa(i)]=Fa(p);
				}
			}
			broken[p]=0;
		}
		else {
    
    
			scanf("%d%d",&p,&q);
			puts(Fa(p)==Fa(q) ? "SUCCESS" : "FAIL");
		}
	}
	
	return 0;
}

2. POJ-1611 The Suspects

//https://vjudge.net/problem/POJ-1611
#include <cstdio>
#define N 30005

int f[N],vis[N];
int Fa(int x) {
    
    return f[x]==x ? x : f[x]=Fa(f[x]);}
int n,m,ans,k,u,v,fu,fv,tmp;

int main()
{
    
    
	while (1) {
    
    
		scanf("%d%d",&n,&m);
		if (n==0 && m==0) {
    
    
			break;
		}
		
		for (int i=0; i<n; i++) {
    
    
			f[i]=i;
			vis[i]=0;
		}
		
		while (m--) {
    
    
			scanf("%d",&k);
			if (k<=0) {
    
    
				continue;
			}
			
			scanf("%d",&v);
			fv=Fa(v);
			while (--k) {
    
    
				u=v;
				fu=fv;
				
				scanf("%d",&v);
				fv=Fa(v);
				
				if (fu!=fv) {
    
    
					ans--;
					f[fu]=fv;
				}
			}
		}
		
		tmp=Fa(0);
		ans=0;
		for (int i=0; i<n; i++)
			ans+=(Fa(i)==tmp);
		
		printf("%d\n",ans);
		
	}
	return 0;
}

3. HDU-1213 How Many Tables

//https://vjudge.net/problem/HDU-1213
#include <cstdio>
#include <iostream>
using namespace std;

short int f[1000],T,n,m,u,v,fu,fv;
inline int Fa(int x) {
    
    
	return f[x]==x ? x : f[x]=Fa(f[x]);
}

int main()
{
    
    
	cin >>T;
	while (T--) {
    
    
		cin >>n >>m;
		for (int i=0; i<n; i++) {
    
    
			f[i]=i;
		}
		while (m--) {
    
    
			cin >>u >>v;
			u--,v--;
			fu=Fa(u);
			fv=Fa(v);
			if (fu<fv) {
    
    
				swap(fu,fv);
			}
			if (fu!=fv) {
    
    
				n--;
				f[fu]=fv;
			}
		}
		cout <<n <<endl;
	}
	return 0;
}

4. HDU-3038 How Many Answers Are Wrong

带权并查集
写了篇博客
https://blog.csdn.net/jackypigpig/article/details/113348863

//https://vjudge.net/problem/HDU-3038
#include <cstdio>

//设当前节点为 x 
//f: 指向的父节点 (f>x) 
//s: 区间 (x,f] 的和 (左开右闭) 
int f[200005],s[200005];
int n,m,a,b,fa,fb,z,ans;

int Fa(int x)
{
    
    
	if (f[x]!=x) {
    
    
		int tmp=f[x];
		f[x]=Fa(tmp);	//先压缩好父节点的路径,维护好其 s[] 值后才能计算当前节点的 s[] 值 
		s[x]+=s[tmp];
	}
	return f[x];
}

void init() {
    
    
	ans=0;
	for (int i=0; i<=n; i++) {
    
    	//注意从 0 开始,因为开区间,会用到 0 
		f[i]=i;
		s[i]=0;
	}
}

int main()
{
    
    
	while (scanf("%d%d",&n,&m)!=EOF) {
    
    
		
		init();
	
		while (m--) {
    
    
			scanf("%d%d%d",&a,&b,&z);
			a--;
			fa=Fa(a);
			fb=Fa(b);
			
			if (fa==fb) {
    
    
				ans+=(s[a]-s[b]!=z);	//判断是否失败 
			}
			else {
    
    
				f[fa]=fb;
				s[fa]=z+s[b]-s[a];	//向量加减得到 
			}
		}
		
		printf("%d\n",ans);
	}
	return 0;
}

5. POJ-1182 食物链

同样,给边附一个取3模意义下的权值,来个带权值并查集即可。

//https://vjudge.net/problem/POJ-1182
#include <cstdio>
#define N 50005

int f[N];	//并查集 
int g[N];	//与父亲的关系 (0:x=f 1:x>f 2:x<f) 
int ans,n,k,D,a,b,fa,fb,p;

int Fa(int x)
{
    
    
	if (f[x]!=x) {
    
    
		int tmp=f[x];
		f[x]=Fa(tmp);
		g[x]=(g[x]+g[tmp])%3;
	}
	return f[x];
}

void init()
{
    
    
	ans=0;
	for (int i=1; i<=n; i++) {
    
    
		f[i]=i;
		g[i]=0;
	}
}

int main()
{
    
    
	scanf("%d%d",&n,&k);
	init();
	while (k--) {
    
    
		scanf("%d%d%d",&D,&a,&b);
		
		if (a>n || b>n) {
    
    
			ans++;
			continue;
		}
		
		p=(D==2);	//a->b = p
		
		fa=Fa(a);
		fb=Fa(b);
		if (fa==fb) {
    
    
			ans+=((g[a]-g[b]+3)%3!=p);
		}
		else {
    
    
			f[fa]=fb;
			g[fa]=(p+g[b]-g[a]+3)%3;
		}
	}
	printf("%d\n",ans);
	return 0;
}

6.

7. POJ-1456 Supermarket

按利润从大到小一次选,能选就选,记下时间,利用并查集压缩路径。

#include <cstdio>
#include <algorithm>
#define I c[i]
using namespace std;
long long ans,n,t,f[10002],p[10002],d[10002],c[10002];

bool cmp(long long x, long long y)
{
    
    
	return p[x]>p[y];
}

long long Fa(long long &x)
{
    
    
	return f[x]==x ? x : f[x]=Fa(f[x]);
}

int main()
{
    
    
	while (scanf("%lld",&n)==1)
	{
    
    
		ans=0;
		for (long long i=0; i<=10000; i++)
			f[i]=i;
		for (long long i=1; i<=n; i++)
		{
    
    
			scanf("%lld%lld",&p[i],&d[i]);
			c[i]=i;
		}
		sort(c+1,c+n+1,cmp);
		
		for (long long i=1; i<=n; i++)
		{
    
    
			t=Fa(d[I]);
			if (t>0)
			{
    
    
				ans+=p[I];
				f[t]=t-1;
			}
		}
		
		printf("%lld\n",ans);
		
	}
	return 0;
}

8. POJ-1733 Parity game

带权并查集

#include <cstdio>
#include <map>
using namespace std;
map<int, int> mp;
int L,Q,cnt,l[5005],r[5005],DD[5005],f[10005],v[10005];

int Fa(int x)
{
    
    
	if (f[x]==x)
	{
    
    
		return x;
	}
	int tmp=f[x];
	f[x]=Fa(tmp);
	v[x]=(v[x]+v[tmp]+2)%2;
	return f[x];
}

int main()
{
    
    
	char s[8];
	int fail,a,b,D,fa,fb;
	
	while (scanf("%d",&L)==1)
	{
    
    
		scanf("%d",&Q);
		
		mp.clear();
		cnt=0;
		
		fail=Q;
				
		for (int i=1; i<=Q; i++)
		{
    
    
			scanf("%d%d%s",&l[i],&r[i],s);			
			DD[i]=(s[0]=='o');
			l[i]--;
			if (!mp[l[i]])
				mp[l[i]]=++cnt;
			if (!mp[r[i]])
				mp[r[i]]=++cnt;
		}
		
		for (int i=1; i<=cnt; i++)
		{
    
    
			f[i]=i;
			v[i]=0;
		}
		
		for (int i=1; i<=Q; i++)
		{
    
    
			a=mp[l[i]];
			b=mp[r[i]];
			
			fa=Fa(a);
			fb=Fa(b);
			
			D=DD[i];
			
			if (fa==fb)
			{
    
    
				if ((v[a]-v[b]+2)%2!=D)
				{
    
    
					fail=i-1;
					break;
				}
			}
			else
			{
    
    
				v[fa]=(D-v[a]+v[b]+2)%2;
				f[fa]=fb;
			}
		}
		
		printf("%d\n",fail);
		
	}
	return 0;
}

9. POJ-1984 Navigation Nightmare

带权并查集

#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 40005
using namespace std;
long long n,m,aa[N],bb[N],ll[N];
long long c[10005],cnt,k,q[10005][3];
long long a,b,l,fa,fb;
long long fx[N],fy[N],vx[N],vy[N];
char s,ss[N][2];

bool cmp(int x, int y)
{
    
    
	return q[x][2]<q[y][2];
}

long long Fa(long long x, long long f[], long long v[])
{
    
    
	if (f[x]==x)
	{
    
    
		return x;
	}
	long long tmp=f[x];
	f[x]=Fa(tmp,f,v);
	v[x]+=v[tmp];
	return f[x];
}

void solve(long long A, long long B)
{
    
    
	long long fxA,fxB,fyA,fyB;
	fxA=Fa(A,fx,vx);
	fxB=Fa(B,fx,vx);
	fyA=Fa(A,fy,vy);
	fyB=Fa(B,fy,vy);
	if (fxA!=fxB || fyA!=fyB)
	{
    
    
		puts("-1");
		return;
	}
	printf("%lld\n",abs(vx[A]-vx[B])+abs(vy[A]-vy[B]));
}

int main()
{
    
    
	while (scanf("%lld%lld",&n,&m)==2)
	{
    
    
		
		for (long long i=1; i<=m; i++)
		{
    
    
			scanf("%lld%lld%lld%s",&aa[i],&bb[i],&ll[i],ss[i]);
			if (ss[i][0]=='S' || ss[i][0]=='W')
			{
    
    
				ll[i]=-ll[i];
			}
		}
		scanf("%lld",&k);
		for (long long i=1; i<=k; i++)
		{
    
    
			scanf("%lld%lld%lld",&q[i][0],&q[i][1],&q[i][2]);
			c[i]=i;
		}
		sort(c+1,c+k+1,cmp);
		
		// init
		for (int i=1; i<=n; i++)
		{
    
    
			fx[i]=fy[i]=i;
			vx[i]=vy[i]=0;
		}
		
		cnt=1;
		for (long long i=1; i<=m; i++)
		{
    
    
			a=aa[i],b=bb[i],l=ll[i],s=ss[i][0];
			if (s=='E' || s=='W')
			{
    
    
				fa=Fa(a,fx,vx);
				fb=Fa(b,fx,vx);
				if (fa!=fb)
				{
    
    
					vx[fa]=l-vx[a]+vx[b];
					fx[fa]=fb;
				}
				
				fa=Fa(a,fy,vy);
				fb=Fa(b,fy,vy);
				if (fa!=fb)
				{
    
    
					vy[fa]=vy[b]-vy[a];
					fy[fa]=fb;
				}
			}
			else
			{
    
    
				fa=Fa(a,fy,vy);
				fb=Fa(b,fy,vy);
				if (fa!=fb)
				{
    
    
					vy[fa]=l-vy[a]+vy[b];
					fy[fa]=fb;
				}
				
				fa=Fa(a,fx,vx);
				fb=Fa(b,fx,vx);
				if (fa!=fb)
				{
    
    
					vx[fa]=vx[b]-vx[a];
					fx[fa]=fb;
				}
			}
			
			while (cnt<=k && q[cnt][2]==i)
			{
    
    
				solve(q[cnt][0],q[cnt][1]);
				cnt++;				
			}
			
			if (cnt>k)
			{
    
    
				break;
			}
		}
	}
	return 0;
}

10. POJ-2492 A Bug’s Life

#include <cstdio>
int f[2005],v[2005];

int Fa(int x)
{
    
    
	if (f[x]==x)
	{
    
    
		return x;
	}
	int tmp=f[x];
	f[x]=Fa(tmp);
	v[x]^=v[tmp];
	return f[x];
}

int main()
{
    
    
	int T,n,m;
	scanf("%d",&T);
	for (int t=1; t<=T; t++)
	{
    
    
		scanf("%d%d",&n,&m);
		for (int i=1; i<=n; i++)
		{
    
    
			f[i]=i;
			v[i]=0;
		}
		int fail=0,a,b,fa,fb;
		for (int i=1; i<=m; i++)
		{
    
    
			scanf("%d%d",&a,&b);
			if (fail)
			{
    
    
				continue;
			}
			fa=Fa(a);
			fb=Fa(b);
			if (fa==fb)
			{
    
    
				if (v[a]^v[b]!=1)
				{
    
    
					fail=1;
				}
			}
			else
			{
    
    
				v[fa]=1^(v[a]^v[b]);
				f[fa]=fb;
			}
		}
		printf("Scenario #%d:\n",t);
		puts(fail ? "Suspicious bugs found!" : "No suspicious bugs found!");
		if (t<T)
			puts("");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jackypigpig/article/details/113329997