zoukankan      html  css  js  c++  java
  • 【POJ1182】 食物链 (带权并查集)

    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
    
    
    
    
    
    

    并查集距离大法好!!!

    若x->y 那么x到y距离为1(y到x距离为-1)

    若x--y 那么x到y距离为0

    那么mod 3相等就是不矛盾的。

    距离就是带权并查集维护。。

    话说我自Y的提根大法总是打错ORZZZZZ。。。

    就是合并x和y并查集的时候,可以先把x提到并查集的根,然后让y成为他的父亲。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 #define Maxn 50010
    10 
    11 int fa[Maxn],g[Maxn];
    12 
    13 int ffa(int x)
    14 {
    15     int now=fa[x];
    16     if(fa[x]!=x) fa[x]=ffa(fa[x]),g[x]=(g[x]+g[now])%3;
    17     return fa[x];
    18 }
    19 
    20 int mm(int x)
    21 {
    22     return (x%3+3)%3;
    23 }
    24 
    25 int main()    
    26 {
    27     int n,k;
    28     scanf("%d%d",&n,&k);
    29     for(int i=1;i<=n;i++) fa[i]=i,g[i]=0;
    30     int sum=0;
    31     for(int i=1;i<=k;i++)
    32     {
    33         int d,x,y;
    34         scanf("%d%d%d",&d,&x,&y);
    35         if(x>n||y>n) {sum++;continue;}
    36         if(d==1)
    37         {
    38             if(ffa(x)!=ffa(y))
    39             {
    40                 // fa[ffa(x)]=ffa(y);
    41                 int now=ffa(x);
    42                 fa[now]=x;g[now]=-g[x];
    43                 fa[x]=y;g[x]=0;
    44             }
    45             else
    46             {
    47                 if(mm(g[x])!=mm(g[y])) sum++;
    48             }
    49         }
    50         else
    51         {
    52             if(ffa(x)!=ffa(y))
    53             {
    54                 // fa[ffa(x)]=ffa(y);
    55                 int now=ffa(x);
    56                 fa[now]=x;g[now]=-g[x];
    57                 fa[x]=y;g[x]=1;
    58             }
    59             else
    60             {
    61                 if(mm(g[x]-g[y])!=1) sum++;
    62             }
    63         }
    64     }
    65     printf("%d
    ",sum);
    66     return 0;
    67 }
    View Code

    2016-11-11 22:04:38

  • 相关阅读:
    Intellij IDEA中Maven解决依赖失效
    Spring Boot 推荐的基础 POM 文件
    Spring Boot启动流程详解(一)
    spring boot应用启动原理分析
    Spring Boot 配置文件详解:Properties和YAML
    Spring Boot 属性配置和使用
    Arcgis for js载入天地图
    Android菜鸟的成长笔记(28)——Google官方对Andoird 2.x提供的ActionBar支持
    Android仿IOS回弹效果 ScrollView回弹 总结
    Android开发有用的站点
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6055781.html
Copyright © 2011-2022 走看看