题目地址
用relaton[]数组保存结点与父节点的关系
同时要考虑两个集合并的时候,在状态压缩时要判断子结点与新的父节点的关系
思路来源:
http://blog.csdn.net/qq_33901573/article/details/52005905
http://blog.csdn.net/roney_win/article/details/9408571
#include<iostream>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=50000+5;
int p[maxn],r[maxn];//relation
int getParent(int x){if(p[x]==x) return x;int xp=getParent(p[x]);r[x]=(r[x]+r[p[x]])%3;return p[x]=xp;
}void merge(int d,int xp,int yp,int x,int y)
{p[yp]=xp;r[yp]=(3+(d-1)+r[x]-r[y])%3;
}
int main()
{int N,K,D,X,Y;cin>>N>>K;int wrong=0;for(int i=1;i<=N;i++) p[i]=i;while(K--){cin>>D>>X>>Y;if(X>N||Y>N) wrong++;else if(D==2&&X==Y) wrong++;else {int xp=getParent(X);int yp=getParent(Y);if(xp!=yp) merge(D,xp,yp,X,Y);else{if(D==1&&r[X]!=r[Y]) wrong++; else if(D==2&&((r[Y]-r[X]+3)%3)!=1) wrong++;} }}cout<<wrong;return 0;
}