See the link and query set. Take the POJ 1182 food chain as an example.
A simple link and query set can easily create a directed Ring Based on the given relationship, and the relationship between the two becomes the distance between the two.
For this question:
If u and v are not in a set, this statement is legal (the last two are ignored temporarily, the same below ).
When fu is changed to fv, an edge with the weight of w must be added. w is equal to (w + ru) % 3 = (rv + (D = 1? 0: 1) % 3 (ru, rv are respectively u, v and fv relationship, that is, distance ).
When D = 2, 1 is added because the distance between u and fv is 1 greater than that between v and fv.
Similarly, when D = 1, it indicates that the distance from the two to the fv should be equal.
If u and v are in a set, you only need to judge ru % 3 = (rv + (D = 1 ?) : 1) % 3 is true.
However, the data on this question is a bit pitfall. It is impossible to write multiple input sets.
#include #include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(linker, "/STACK:1024000000");#define EPS (1e-8)#define LL long long#define ULL unsigned long long#define _LL __int64#define INF 0x3f3f3f3fusing namespace std;struct N{ int fa,re;} st[50010];int Find(int x,int &R){ int f,re = 0; f = x; while(f != st[f].fa) { re = (re+st[f].re)%3; f = st[f].fa; } R = re; int tre = 0,temp,tf; while(x != st[x].fa) { tf = st[x].fa; temp = st[x].re; st[x].re = (re-tre+3)%3; tre = (tre+temp)%3; st[x].fa = f; x = tf; } return f;}bool Merge(int w,int u,int v){ int ru,rv; int fu = Find(u,ru); int fv = Find(v,rv); if(fu != fv) { st[fu].fa = fv; if(w == 2) st[fu].re = ((rv+1)%3 - ru + 3)%3; else st[fu].re = (rv%3- ru + 3)%3; } else { if(w == 1 && ru != rv) return false; if(w == 2 && ru != (rv+1)%3 ) return false; } return true;}int main(){ int n,k; int i,j,u,v,w; scanf("%d %d",&n,&k); { for(i = 1; i <= n; ++i) st[i].fa = i,st[i].re = 0; int ans = 0; while(k--) { scanf("%d %d %d",&w,&u,&v); if(u > n || v > n || (w == 2 && u == v)) { ans++; continue; } if(Merge(w,u,v) == false) { ans++; } } printf("%d\n",ans); } return 0;}