NOI 2001 食物链 并查集A的第一题。

来源:互联网 发布:mac 修改文件夹权限 编辑:程序博客网 时间:2024/04/27 18:29

  这题确定的是1 ~ N 动物的三角捕食关系。

  因为可能存在多个三角圈。所以在设置的时候用find这个函数来确定三角的源头。

  就比如说 a , b ,c ,d ,e ,f , g 他们在不同的三角捕食关系中,但是他们是在总三角关系的同一个等级中。那么我们把p[b] = a , p[c] = a , ... 让他们的源头都指向a,这样每次比较都是用源头a来进行,就不会忽略已有的情况或者发生矛盾了。

#include<cstdio>#define lie {cnt++;continue;}#define rise(i,a,b) for(int i=a;i<=b;i++)const int MAXN = 100000 * 3 + 1; int p[MAXN], fa[MAXN];void pre( int n )/* to make original Triangle predator-prey relationships. && the sourse of every number. */{rise( i , 1 , 3 * n ) p[i] = i;rise( i , 1 , n ){fa[i] = i + n;fa[ i + n ] = i + n + n;fa[ i + n + n ] = i; }}int find( int x )/*  to find the source of x, such as if a <=> b , b <=> c , c <=> d , ... , ( a , b , c , d ... are in the same level ) we use a to represent b , c , d ... */{    if( x != p[x] ) p[x] = find( p[x] );    return p[x];}int doit( int k , int n ){int cnt = 0, w, x, y;rise( i , 1 , n ){    scanf( "%d%d%d" , &w, &x, &y );    if( x > k || y > k ) lie;    int a[3], b[3];    /* a[i] is the Triangle predator-prey relationships of a[0]. */        a[0] = find(x)  ; b[0] = find(y)  ;        a[1] = fa[a[0]] ; b[1] = fa[b[0]] ;        a[2] = fa[a[1]] ; b[2] = fa[b[1]] ;        bool flag = false;        rise( i , 0 , 2 )        if( a[0] == b[i] )        {        flag = true;        break;        }        /* if flag == true , it means x , y has some relationship.*/        if( w == 1 )/* if x , y in the same level. */         {        if( flag && a[0] != b[0] ) lie;        if( !flag )        rise( i , 0 , 2 )        p[ b[i] ] = a[i];        /* make a[i] the sourse of b[i]. */        }        else if( w == 2 )        {        if( x == y ) lie;        if( !flag )        rise( i , 0 , 2 )        p[ b[i] ] = a[ ( i + 2 ) % 3 ];            else             {            if( fa[ b[0] ] != a[0] ) lie;            }        }}return cnt;}int main(){int n, k, cnt = 0, type = 0;scanf( "%d%d", &k, &n );    pre( n ); printf( "%d\n" , doit( k , n ) );return 0;}


0 0
原创粉丝点击