zoukankan      html  css  js  c++  java
  • POJ 1182(权值并查集,向量?)

    食物链
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 108628   Accepted: 32960

    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
    题目中文不解释
    虽然我wa了三四发,T了一发(卡scanf),但是感觉这题想明白了还是好写,纸上画画就会了,注意d[]数组在存数的时候别忘记(d[]+3)%3,因为我要保证d只能是三个数,1,2,0;
    1代表fa[i]吃i
    2反过来
    0代表二者同种族

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <iomanip>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <set>
    #include <vector>
    //const int maxn = 1e5+5;
    #define ll long long
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    
    #define MAX INT_MAX
    #define FOR(i,a,b) for( int i = a;i <= b;++i)
    #define bug cout<<"--------------"<<endl
    using namespace std;
    int fa[51000],d[51000];
    int cnt,n,m;
    int Find(int x)
    {
        //bug;
        if(x == fa[x]) return x;
        int root = Find(fa[x]);
        d[x] = (d[x] + d[fa[x]]+3)%3;
        return fa[x] = root;
    }
    int main()
    {
    
          ios::sync_with_stdio(false);
        scanf("%d%d",&n,&m);
        FOR(i,1,n) fa[i] = i;
        FOR(i,1,m)
        {
            int k,x,y;
            scanf("%d%d%d",&k,&x,&y);
            if(x > n || y > n) {cnt++;continue;}
            if(k==2 && x==y){cnt++;continue;}
            int fx = Find(x);
            int fy = Find(y);
            if(fx == fy)
            {
                int temp = d[x] - d[y];
                if(k == 1 && temp != 0)
                {
                    cnt++;
                    continue;
                }
                else if(k == 2 )
                {
                    if((d[x]-d[y]+3)%3 !=2 ) cnt++;
                }
    
            }
            else
            {
               if(k == 1)
               {
                   fa[fy] = fx;
                   d[fy] = (d[x] - d[y]+3)%3;
               }
               else if(k == 2)
               {
                   fa[fy] = fx;
                   d[fy] = (d[x] - d[y] + 1+3)%3;
               }
            }
        }
        printf("%d
    ",cnt);
    }

  • 相关阅读:
    MySQL监控全部执行过的sql语句
    Linux之网络编程:时间服务器
    人生哲理 |南怀瑾最经典的50句话
    TCP/IP协议(一)网络基础知识 网络七层协议
    Linux下进程通信之管道
    一个完整的项目管理流程
    Linux编程之select
    (笔记)电路设计(十四)之放大器的应用
    ds18b20采集温度并上报服务器
    java中基于swing库自定义分页组件
  • 原文地址:https://www.cnblogs.com/jrfr/p/11407408.html
Copyright © 2011-2022 走看看