zoukankan      html  css  js  c++  java
  • 洛谷P2024食物链题解

    这道题我们用带权并查集来搞
    既然题目中有三种关系(同类,天敌,猎物),所以我们设定不同的距离来表示不同的关系。
    (dis(x,y)=0)表示(x)(y)是同类,(dis(x,y)=1)表示(x)(y),在计算距离的时候%3,则(dis(x,y)=2)时,(y)(x)
    在实现距离的时候,设(dis[x])表示(x)到根的距离,(dis(x,y))((dis[y]-dis[x]+3)%3)来实现
    这样在路径压缩的时候就要注意维护距离
    具体看代码叭

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,k,fa[50009],all,cnt,dis[50009];//dis[x]表示x到根的距离
    int find(int x)
    {
    	if(fa[x]==x) return x;
    	int xx=fa[x];
            fa[x]=find(fa[x]);//先计算父亲的距离再搞这个点的距离
            dis[x]=(dis[x]+dis[xx]+3)%3;
    	return fa[x];
    }
    int main()
    {
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++) fa[i]=i;
    	for(int i=1;i<=k;i++)
    	{
    		int opt,x,y;
    		scanf("%d%d%d",&opt,&x,&y);
    		if(x>n||y>n){all++;continue;}
    	        int f1=find(x),f2=find(y);
    		if(opt==1)
    	        {
    	                if(f1!=f2) 
    			{
    	        	 dis[fa[x]]=(dis[y]-dis[x]+3)%3;
    	                 fa[fa[x]]=fa[y];
    			}
    			else
    			{
    			 if(dis[x]!=dis[y]) all++;
    			}
    	        }
    		if(opt==2)
    	        {
    	    	 if(f1!=f2)
    	    	 {
    	    		dis[fa[y]]=(dis[x]-dis[y]+4)%3;
    	    		fa[fa[y]]=fa[x];
    	    	 }
    	    	 else
    	    	 {
    	    		if(dis[y]!=(dis[x]+1)%3) all++;
    	    	 }
    		}
    	}
    	printf("%d
    ",all);
    }
    

    当然还有开三个并查集的神奇解法。
    规定并查集1吃并查集2,并查集2吃并查集3,并查集3吃并查集1,按照吃的关系维护就好
    当然这种方法我莫得代码

  • 相关阅读:
    pku 2446 Chessboard
    POJ 2724 Purifying Machine
    14 Flash内存控制器(FMC)
    10 PWM发生器和捕捉定时器
    15 I2C总线控制器
    18 RTX Kernel实时系统
    17模拟数字转换
    19.1 详解startup_M051.s
    16串行外围设备接口(SPI)控制器
    13看门狗
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/12774053.html
Copyright © 2011-2022 走看看