zoukankan      html  css  js  c++  java
  • poj1182~食物链~带权并查集

    食物链
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 63050   Accepted: 18482

    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

    Source

     
     
    0表示同类、1表示x吃y,2表示y吃x
     
    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define maxsize 50050
    
    int pre[maxsize];
    int dist[maxsize];
    
    int init(int n)
    {
        for(int i=1;i<=n;i++)
        {
            pre[i]=i;
            dist[i]=0;
        }
    }
    
    int find(int x)
    {
        if(x==pre[x]) return x;
        int tmp=find(pre[x]);
        dist[x]=(dist[pre[x]]+dist[x])%3;
        pre[x]=tmp;
        return tmp;
    }
    
    
    int Union(int w,int u,int v)
    {
        int p=find(u);
        int q=find(v);
        if(p!=q)
        {
            pre[p]=q;
            dist[p]=(3+w+dist[v]-dist[u])%3;
        }
        else
        {
            if((dist[u]-dist[v]+3)%3!=w) return 0;
        }
        return 1;
    }
    int main()
    {
        int n,k;
        scanf("%d %d",&n,&k);
            int cnt=0;
            init(n);
            int w,u,v;
            while(k--)
            {
    
                scanf("%d %d %d",&w,&u,&v);
                if(u>n||v>n||(w==2&&u==v)) {cnt++;}
                else if(!Union(w-1,u,v)) {cnt++;}
            }
            printf("%d
    ",cnt);
    
        return 0;
    }
    

      

  • 相关阅读:
    WPF控件操作之改变父控件之TabControl示例
    WPF里面的DockPanel的Fill去哪了,如何填满整个空间
    [原创]winform自定义控件之类属性-多重属性-可折叠属性
    WinForm之DataBinding
    WinForm自定义控件之DefaultValue的误解
    code snippet:依赖属性propa的小技巧
    【原创】WinForm中实现单独Time控件的方式
    node.js安装本地模块遇到的目录锁定问题【新手问题】
    《程序员思维修炼》之德雷福斯模型
    IOptions、IOptionsMonitor以及IOptionsSnapshot
  • 原文地址:https://www.cnblogs.com/hellohacker/p/5722087.html
Copyright © 2011-2022 走看看