POJ-1703-Find them, Catch them-带权并查集

裸的带圈并查集

更新祖先的时候 顺便 维护一下 距离就可以了,距离只有0.1,分别代表两个帮派

合并的时候,更新距离

/*   x->fx 
y->fy    
dis(fx->fy)=dis(x->fx)+dis(y->fy )+dis(x->y)
对应了 path[fx]=(path[x]+path[y]+ 1)%2;
 */



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;  
int fa[100005];
int path[100005];  //记录自己到祖先的距离
int find(int x)  //找到祖先,并更新自己到祖先的距离
{
	if (x==fa[x]) 
		return x;
	else
	{
		int fx=find(fa[x]);
		path[x]=(path[x]+path[fa[x]])%2;  //维护与祖先的关系
		return fa[x]=fx;
	}
}
int vis[100005];
int main()
{  
	int n,m;
	int t,i,x,y;
	char op;
	cin>>t;
	while(t--)
	{
		
		scanf("%d%d",&n,&m);getchar();
		for (i=1;i<=n;i++)
			fa[i]=i,vis[i]=0,path[i]=0;
		for (i=1;i<=m;i++)
		{
			scanf("%c %d %d",&op,&x,&y);
			getchar();
			int fx=find(x);
			int fy=find(y);
			if (op=='D')
			{
				if (fx!=fy)
				{  
					fa[fx]=fy;  
					path[fx]=(path[y]+path[x]+ 1)%2; 
					// path[fx]=( path[x]+ 1)%2; 煞笔了,之前写成这个了
					/*   x->fx 
						 y->fy    
						 dis(fx->fy)=dis(x->fx)+dis(y->fy )+dis(x->y)
			对应了				path[fx]=(path[x]+path[y]+ 1)%2;
					  */
				}
			}
			else
			{  	
				if (fx==fy)
				{
				if (path[x]==path[y] ) 
						printf("In the same gang.\n");
					else
					 
						printf("In different gangs.\n");
				}
				else
				 	printf("Not sure yet.\n");
			}
			
		}
	}
	
	
	return 0;
}


你可能感兴趣的:(POJ-1703-Find them, Catch them-带权并查集)