Sicily10481(并查集)

x y L其实表示x和y不同,x y T表示x和y相同。

rank[x]表示第x个元素和其根节点的关系,rank[x]=1表示和根节点不同,rank[x]=0表示和根节点相同。

特别注意当B集合合并到A集合的时候,B集合的根节点的rank值需要更新,且其所有子节点也可能需要更新,在路径压缩的时候进行特殊处理确保子节点能够得到正确的rank值。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;

int parent[10005];
int rank[10005];
char s[2];
int getpar(int a)
{
	if (parent[a]!=a)
	{
	  int tempar=getpar(parent[a]);
	  if (rank[parent[a]])
	    rank[a]=!rank[a];
    parent[a]=tempar;
  }
  return parent[a];
}

void unio(int x,int y)
{
	int xp=getpar(x);
	int yp=getpar(y);
	parent[yp]=xp;
	if ( (s[0]=='T' && rank[x]!=rank[y]) || (s[0]=='L' && rank[x]==rank[y]) )
	  rank[yp]=1;
}

int main()
{
	int m,n,x,y,i,j;
	bool end=false;
	
	scanf("%d%d",&m,&n);
	int record=n;
	
	for (i=1;i<=m;i++)
	  parent[i]=i;
	  
	for (i=0;i<n;i++)
	{
		scanf("%d%d%s",&x,&y,s);
	
	  if (!end)
	  {
	  	int xp=getpar(x);
	  	int yp=getpar(y);
	  	if (xp==yp)
	  	{
	  		if ((s[0]=='L' && rank[x]==rank[y]) || (s[0]=='T' && rank[x]!=rank[y]))
	  		{
	  			end=true;
	  			record=i;
	  		}
	  	}
	  	else
	  	  unio(x,y);
  	}
	}
	printf("%d\n",record);
}



你可能感兴趣的:(Sicily10481(并查集))