zoukankan      html  css  js  c++  java
  • POJ1182 食物链 【并查集变种】

    挺简单的

    N个元素扩展为 3*N个

    i-A i-B i-C

    A吃B吃C吃A

    挑战程序设计的89面

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    using namespace std;
    int N,K;
    const int MAX_N=333333;
    //并查集
    int par[MAX_N];
    int rank[MAX_N];//树的高度
    void init(int n)
    {
    	for(int i=0;i<n;i++)
    	{
    		par[i]=i;
    		rank[i]=0;
    	}
    }
    int find(int x)//
    {
    		if(par[x]==x)
    			return x;
    		else
    			return par[x]=find(par[x]);
    }
    //合并x和y所属的集合
    void unite(int x,int y)
    {
    	x=find(x);
    	y=find(y);
    	if(x==y)
    		return;
    	if(rank[x]<rank[y])
    		par[x]=y;
    	else
    	{
    		par[y]=x;
    		if(rank[x]==rank[y])
    			rank[x]++;
    	}
    }
    //推断x和y是否同属于一个集合
    bool same(int x, int y)
    {
    	return find(x)==find(y);
    }
    int main()
    {
    	#ifndef ONLINE_JUDGE
    		freopen("G:/1.txt","r",stdin);
    		freopen("G:/2.txt","w",stdout);
    	#endif
        scanf("%d%d",&N,&K);
    	init(3*N);
    	int kind,a,b;
    	int ans=0;
    	for(int i=0;i<K;i++)
    	{
    		scanf("%d%d%d",&kind,&a,&b);
    		int x=a-1;
    		int y=b-1;
    		if(x<0||x>=N||y<0||y>=N)
    		{
    			ans++;
    			continue;
    		}
    		if(kind==1)
    		{
    			if(same(x,y+N)||same(x,y+2*N))
    			{
    				ans++;
    				continue;
    			}
    			unite(x,y);
    			unite(x+N,y+N);
    			unite(x+2*N,y+2*N);
    		}
    		else
    		{
    			if(same(x,y)||same(x+N,y+N)||same(x+2*N,y+2*N)||same(x,y+2*N))
    			{
    				ans++;
    				continue;
    			}
    			unite(x,y+N);
    			unite(x+N,y+2*N);
    			unite(x+2*N,y);
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    


     

  • 相关阅读:
    重定向管道
    系统安全
    Linux启动流程
    压缩解压
    Vim
    ssh
    sudo
    Raid
    rsync
    quota
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4247946.html
Copyright © 2011-2022 走看看