• POJ-1182 分组并查集


    今天刚发现,之前做的并查集只是贴模板基本就能过,题意改变一点,自己还是不懂,其实我还没入门呢。。。

    题意:食物链,A吃B,B吃C,C吃A,输入m组数据:

    1 a b:a 和 b 是同一类

    2 a b:a吃b

    判断这m组数据有几句是假话。

    假话条件:

    1)在2的情况下,a == b;

    2)a > n || b > n;

    3)和前面的语句冲突;

    思路:推荐一篇好的博客:http://cavenkaka.iteye.com/category/217940

    其实在这里才明白Rank[]数组的意义,表示的是x 和 p[x] 的关系;博客挺详细的,学到不少,看下一步用不用得上了。。。

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <string>
     7 #include <sstream>
     8 #include <algorithm>
     9 #define Max 2147483647
    10 #define INF 0x7fffffff
    11 #define N 50010
    12 #define ll long long
    13 #define mem(a,b) memset(a,b,sizeof(a))
    14 #define repu(i, a, b) for(int i = (a); i < (b); i++)
    15 const double PI=-acos(-1.0);
    16 using namespace std;
    17 int rank[N],p[N];
    18 void init(int n)
    19 {
    20     repu(i,1,n+1)
    21     {
    22         rank[i] = 0;
    23         p[i] = i;
    24     }
    25 }
    26 int find_set(int x)
    27 {
    28     if(x!=p[x])
    29     {
    30         int fx=find_set(p[x]);
    31         rank[x]=(rank[x]+rank[p[x]])%3; //注意 是rank[p[x]]而不是rank[fx]
    32         p[x]=fx;
    33     }
    34     return p[x];
    35 }
    36 bool Union(int x,int y,int d)
    37 {
    38     int u = find_set(x);
    39     int v = find_set(y);
    40     printf("%d---%d
    ",u,v);
    41     if(u == v)///如果在同一个集合
    42     {
    43         if((3 - rank[x] + rank[y])%3!=d)///如果符合吃鱼的关系
    44             return true; ///这个关系可以通过举例得出
    45         else
    46             return false;
    47     }
    48     p[v] = u ;
    49     rank[v]=(rank[x]-rank[y]+d+3)%3;///与上式不同 需仔细归纳
    50     return false;
    51 }
    52 int main()
    53 {
    54     int n,m;
    55     scanf("%d%d",&n,&m);
    56     init(n);
    57     int sum = 0,a,b,d;
    58     repu(i,0,m)
    59     {
    60         scanf("%d%d%d",&d,&a,&b);
    61         if((a == b&&d == 2) || a > n || b > n)
    62             sum++;
    63         else if(Union(a,b,d-1))  ///传d-1 方便关系式的表达
    64             sum++;
    65     }
    66     printf("%d
    ",sum);
    67 }
    View Code
  • 相关阅读:
    mysql事务隔离级别回顾
    单链表倒数第K个节点的查找和显示
    mysql 行转列,对列的分组求和,对行求和
    获取分组后统计数量最多的纪录;limit用法;sql执行顺序
    You can't specify target table 'e' for update in FROM clause
    mysql 行转列 (结果集以坐标显示)
    springmvc执行流程 源码分析
    jdk动态代理 案例
    项目日志log管理
    apache和tomcat的区别
  • 原文地址:https://www.cnblogs.com/ACMERY/p/4534794.html
Copyright © 2020-2023  润新知