zoukankan      html  css  js  c++  java
  • Poj 1182种类(带权)并查集

    题目链接

    食物链
    Time Limit: 1000MS Memory Limit: 10000K
    Total Submissions: 44316 Accepted: 12934

    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到死
    有三种动物,用编号i表示第i个动物类型是A, i+n 表示第i个动物类型是B, i+2n表示第i个动物类型是C
    Accepted Code:
     1 /*************************************************************************
     2     > File Name: 1182.cpp
     3     > Author: Stomach_ache
     4     > Mail: sudaweitong@gmail.com
     5     > Created Time: 2014年08月02日 星期六 15时55分36秒
     6     > Propose: 
     7  ************************************************************************/
     8 #include <cmath>
     9 #include <string>
    10 #include <cstdio>
    11 #include <fstream>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 using namespace std;
    16 
    17 const int maxk = 100002;
    18 const int maxn = 50002;
    19 int n, k;
    20 int fa[maxn*3];
    21 
    22 int getfa(int x) {
    23       return x != fa[x] ? fa[x] = getfa(fa[x]) : x;
    24 }
    25 
    26 void unite(int x, int y) {
    27       int xx = getfa(x);
    28     int yy = getfa(y);
    29     if (xx != yy) {
    30           fa[xx] = yy;
    31     }
    32 }
    33 
    34 bool same(int x, int y) {
    35       return getfa(x) == getfa(y);
    36 }
    37 
    38 int main(void) {
    39       scanf("%d %d", &n, &k);
    40     for (int i = 0; i < 3*n; i++) fa[i] = i;
    41     int ans = 0;
    42     int d, x, y;
    43     while (k--) {
    44         scanf("%d %d %d", &d, &x, &y);
    45         x--; y--;
    46         if (x < 0 || x >= n || y < 0 || y >= n) {
    47               ans++;
    48             continue;
    49         }
    50         if (d == 1) {
    51               if (same(x, y+n) || same(x, y+2*n)) {
    52                   ans++;
    53             } else {
    54                   unite(x, y);
    55                 unite(x+n, y+n);
    56                 unite(x+2*n, y+2*n);
    57             }
    58         } else {
    59               if (same(x, y) || same(x, y+2*n)) {
    60                   ans++;
    61             } else {
    62                   unite(x, y+n);
    63                 unite(x+n, y+2*n);
    64                 unite(x+2*n, y);
    65             }
    66         }
    67     }
    68     printf("%d
    ", ans);
    69     return 0;
    70 }
     
    
    
  • 相关阅读:
    linux ubuntu装机到可实现java(eclipse,intellij IDEA,android)开发全过程
    浅谈线程同步的几种方法
    KMP算法,这是我看到的最简单的最好理解的KMP算法
    常用基础算法C++实现
    堆内存和栈内存详解(转载)
    数据结构=。= 链表
    倒排索引--资料1
    倒排索引简单理解
    简单理解Socket
    8.结构体的使用 2015.12.3
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3887348.html
Copyright © 2011-2022 走看看