• 食物链(带全并查集)


    /*
    初始化并查集的所有集合 和根节点直接的关系
    找到父节点
    合并集合,并更新点和父节点直接的关系

    判断是否是真话
    if 父节点不相等 true 加入集合中
    if 相等
    if() 判断在集合中与 根节点的关系对不对 对 true [加入集合]错 false

    主函数:
    创建集合
    找到2点的父节点
    判断是否是真话
    假话 count++
    真话 和并集合
    */

    #include<stdio.h>
    #include<string.h>
    #define MAX 50005
    int father[MAX]={0}; 
    int rank[MAX]={0};
    int k,n;
    void make_set()
    {
    int i;
    for(i=1;i<=n;i++)
    {
    father[i]=i;rank[i]=0;//父节点都是自己 和父节点的关系都是同类0 
    }
    }
    int find_father(int x)//只找到父节点 
    {
    if(father[x]==x) return x;
    
    int lao=father[x];//更新原来集合下所有点的根节点 和 关系值 
    father[x]= find_father(father[x]);
    rank[x]=(rank[x]+rank[lao])%3;
    
    return father[x];
    } 
    void union_set(int r,int x,int y)
    {
    int fx,fy;
    //先将x和y的根节点找到
    fx=find_father(x);
    fy=find_father(y);
    if(fx==fy) return ;
    
    father[fx]=fy;//将x的集合加到y的集合下面
    rank[fx]=(rank[y]+r-rank[x]+3)%3;//+3防止出现负的情况 通过向量可以确定关系 
    }
    int isTrue(int r,int x,int y)
    {
    int fx,fy;
    if(x>n || y>n || ((x==y)&&((r+1)==2)) ) 
    return 0; 
    
    //先将x和y的根节点找到
    fx=find_father(x);
    fy=find_father(y);
    
    if(fx!=fy)//证明原先的集合中没有他们之间的关系 可以加入到集合中
    return 1;
    else
    {
    if(rank[x]==((rank[y]+r)%3))//如果x-y的关系正确
    return 1;
    else
    return 0; 
    } 
    }
    int main(void)
    {
    int i,r,x,y,fx,fy,count=0;
    
    scanf("%d%d",&n,&k);
    make_set();
    for(i=1;i<=k;i++)
    {
    scanf("%d%d%d",&r,&x,&y);
    if(isTrue(r-1,x,y))
    {
    union_set(r-1,x,y);
    }
    else 
    {
    count++;
    }
    }
    printf("%d
    ",count);
    return 0;
    }
  • 相关阅读:
    txt换行追加写入
    np.unique( )的用法
    生成自己想要的任意颜色的图片
    183. 木材加工
    575. 字符串解码
    364. 接雨水 II
    255. Multi-string search
    433. 岛屿的个数
    591. 连接图 III
    918. 三数之和
  • 原文地址:https://www.cnblogs.com/woshijishu3/p/3719604.html
Copyright © 2020-2023  润新知