1. 程式人生 > >POJ1182 食物鏈 查並集

POJ1182 食物鏈 查並集

食物鏈

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 94035 Accepted: 28376

Description

動物王國中有三類動物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 7
1 101 1 
2 1 2
2 2 3 
2 3 3 
1 1 3 
2 3 1 
1 5 5

Sample Output

3
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[150005];
int getfri(int num){  
    if(num!=f[num]){
        f[num]=getfri(f[num]);
    }
    return f[num];
}
void unite(int a,int b){
    int aa=getfri(a);
    int bb=getfri(b);
    f[aa]=bb;
}
bool same(int a,int b){
    int aa=getfri(a);
    int bb=getfri(b);
    if(aa==bb)
        return true;
    else
        return false;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);{
        int ans=0;
        for(int i=0;i<=3*n;i++){
            f[i]=i;
        }
        ///1-同類 2-捕食 3-被捕食
        while(m--){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if(b>n||c>n||b<=0||c<=0){
                ans++;
                continue;
            }
            if(a==1){
                if(same(b,c+n)||same(b,c+2*n))
                    ans++;
                else{
                    unite(b,c);
                    unite(b+n,c+n);
                    unite(b+2*n,c+2*n);
                }
            }
            else{
                if(b==c||same(b,c+n)||same(b,c))
                    ans++;
                else{
                    unite(b,c+2*n);
                    unite(b+n,c);
                    unite(b+2*n,c+n);
                }
            }
        }
        cout<<ans<<endl;
    }
}

設定三個域,第一個為同類,第二個為捕食,第三個為被捕食

比如unite(b+n,c)就表示b捕食c

注意不要多組輸入,WA了一個晚上WA到懷疑人生