zoukankan      html  css  js  c++  java
  • 【NOI2001T1】食物链-并查集

    测试地址

    题目大意:一个地方的动物分A,B,C三类,A吃B,B吃C,C吃A,两种动物之间要么是同类,要么就有吃与被吃的关系。按顺序给定K句话,描述的是某两种动物是同类或某种动物吃某种动物。求这些话中假话的数量(假话的定义在原题中有)。

    做法:用f[i]表示i号动物所属集合的代表动物,r[i]表示i号动物与它所属集合代表动物之间的关系,为0时代表它们是同类,为1时代表i号动物吃它所属集合的代表动物,为2时反之。由于动物之间的关系刚开始是不确定的,因此我们用并查集来记录哪些动物之间的关系是可以确定的。每读入一个关系,如果关系涉及的两种动物不属于同一个集合,则表示它们之间的关系仍不能确定,则认定这句话为真话,合并两个集合。如果它们属于同一个集合,则表示它们之间的关系已经可以确定,则先求出它们之间的关系,再将它与描述中的关系比较,判断是否为假话。关键就在于怎么维护这个关系。这里主要是合并和求某两种动物之间关系的问题:合并时,如有两种动物x,y,关系为d,因为x与f[x]关系为r[x],y与f[y]关系为r[y],得出f[x]和f[y]之间关系为(r[y]+d-r[x]+3) mod 3,括号里加上3是为了防止减的结果为负数,然后再像普通并查集一样合并即可。求两种动物x,y之间关系,可以用上面的推论方法得出它们之间的关系为(r[x]-r[y]+3) mod 3。路径压缩中维护r的方法与上面的推论方法类似,不再赘述。至此,我们已经可以解决这个问题了。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    long n,k,ans=0,f[50010]={0},r[50010]={0};
    
    long find(long x)
    {
      long t;
      if (f[x]==x) return x;
      t=f[x];
      f[x]=find(f[x]);
      r[x]=(r[t]+r[x])%3;
      return f[x];
    }
    
    void merge(long x,long y,long len)
    {
      long fx=find(x),fy=find(y);
      f[fx]=fy;
      r[fx]=(r[y]-r[x]+3+len)%3;
    }
    
    int main()
    {
      scanf("%ld %ld
    ",&n,&k);
      
      for(int i=1;i<=n;i++)
        f[i]=i;
      
      for(int i=1;i<=k;i++)
      {
        long d,x,y;
        scanf("%ld %ld %ld
    ",&d,&x,&y);
        if (x>n||y>n||(d==2&&x==y)) ans++;
    	else
    	{
    	  long fx=find(x),fy=find(y);
    	  if (fx==fy)
    	  {
    	    if ((r[x]-r[y]+3)%3!=d-1) ans++;
    	  }
    	  else merge(x,y,d-1);
    	}
      }
      
      printf("%ld",ans);
      
      return 0;
    }
    


  • 相关阅读:
    正则正数,负数,整数,浮点数校验大全
    只能输入正整数的正则表达式及常用的正则表达式
    Java对返回参数进行处理(JSONObject,getJSONArray等)
    JAVA调用IReport模板生成PDF文件及常见的几个问题解决
    Oracle中关于to_date(),to_char(),to_number()函数的用法
    js将字符串中所有反斜杠替换成正斜杠/
    ext CSS样式
    oracle exist 语句
    【2021.06.12】前去上海市中心见朋友见闻
    牛客网刷题——20210307(刷题第一次)
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793935.html
Copyright © 2011-2022 走看看