標籤:演算法 並查集 poj
本文出自:http://blog.csdn.net/svitter
題意:
動物王國中有三類動物A,B,C,這三類動物的食物鏈構成了有趣的環形。A吃B, B吃C,C吃A。
現有N個動物,以1-N編號。每個動物都是A,B,C中的一種,但是我們並不知道它到底是哪一種。
有人用兩種說法對這N個動物所構成的食物鏈關係進行描述:
第一種說法是"1 X Y",表示X和Y是同類。
第二種說法是"2 X Y",表示X吃Y。
此人對N個動物,用上述兩種說法,一句接一句地說出K句話,這K句話有的是真的,有的是假的。當一句話滿足下列三條之一時,這句話就是假話,否則就是真話。
1) 當前的話與前面的某些真的話衝突,就是假話;
2) 當前的話中X或Y比N大,就是假話;
3) 當前的話表示X吃X,就是假話。
你的任務是根據給定的N(1 <= N <= 50,000)和K句話(0 <= K <= 100,000),輸出假話的總數。
輸入輸出分析:
Input
第一行是兩個整數N和K,以一個空格分隔。
以下K行每行是三個正整數 D,X,Y,兩數之間用一個空格隔開,其中D表示說法的種類。
若D=1,則表示X和Y是同類。
若D=2,則表示X吃Y。
Output
只有一個整數,表示假話的數目。
Sample Input
100 71 101 1 2 1 22 2 3 2 3 3 1 1 3 2 3 1 1 5 5
Sample Output
3
題解:本題目也是並查集的問題。本題目出現了3個不同的集合,集合間存在不同的關係。A-B-C的關係。建立一個n*3的數組,1~n表示A,n+1~2*n表示B, 2*n~3*n表示C由此,可以得出結論輸入資料為1 i j1表示是同類,如果是同類,那麼i,j+n \\ i+n, j+2n \\ i+2n, j分別不屬於同一個集合。同理,j, i+n \\ j + n, i + 2n\\ j+2n, i不可能屬於同一個集合。輸入資料為2 i j2表示i吃j,如果不是同類,那麼i,j \\ i+n, j+n \\ i+2n, j+2n 分別不屬於同一個集合。同理,j, i+n \\ j + n, i + 2n\\ j+2n, i不可能屬於同一個集合。
AC代碼,Time:344MS
//author: svtter//#include <iostream>#include <stdio.h>#include <string.h>#include <vector>#include <map>#include <algorithm>#include <queue>#include <cmath>#define INF 0xffffffusing namespace std;const int MAXN = 150010;int root[MAXN];int n, k;int n3;void init(){ n3 = 3*n; for(int i = 0; i <= n3; i++) root[i] = i;}int getRoot(int i){ if(i == root[i]) return i; return root[i] = getRoot(root[i]);}int a, b;void Merge(int i, int j){ a = getRoot(i); b = getRoot(j); if(a == b) return; root[a] = b;}bool jud(int i, int j){ return getRoot(i) == getRoot(j);}int main(){ int i; int r, t1, t2; int n2; int fal; scanf("%d%d", &n, &k); init(); n2 = n*2; fal = 0; for(i = 0; i < k; i++) { scanf("%d %d %d", &r, &t1, &t2 ); if(t1 > n || t2 > n || jud(t2, t1+n) || jud(t2+n ,t1+n2) || jud(t2+n2, t1)) { fal++; continue; } if(r == 2) { if(jud(t1, t2) || jud(t1+n, t2+n) || jud(t1+n2, t2+n2)) fal++; else { Merge(t1, t2+n); Merge(t1+n, t2+n2); Merge(t1+n2, t2); } } else { if(jud(t1, t2+n) || jud(t1+n, t2+n2) || jud(t1+n2, t2)) fal++; else { Merge(t1, t2); Merge(t1+n2, t2+n2); Merge(t1+n, t2+n); } } } printf("%d\n", fal); return 0;}