• POJ 1182(食物链-另类做法【拆点】)[Template:并查集]


    食物链
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 46039   Accepted: 13400

    Description

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 
    现有N个动物,以1-N编号。每一个动物都是A,B,C中的一种,可是我们并不知道它究竟是哪一种。 
    有人用两种说法对这N个动物所构成的食物链关系进行描写叙述: 
    第一种说法是"1 X Y",表示X和Y是同类。 
    另外一种说法是"2 X Y",表示X吃Y。 
    此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之中的一个时,这句话就是假话,否则就是真话。 
    1) 当前的话与前面的某些真的话冲突,就是假话; 
    2) 当前的话中X或Y比N大,就是假话; 
    3) 当前的话表示X吃X,就是假话。 
    你的任务是依据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。 

    Input

    第一行是两个整数N和K,以一个空格分隔。 
    下面K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,当中D表示说法的种类。 
    若D=1,则表示X和Y是同类。 
    若D=2,则表示X吃Y。

    Output

    仅仅有一个整数,表示假话的数目。

    Sample Input

    100 7
    1 101 1 
    2 1 2
    2 2 3 
    2 3 3 
    1 1 3 
    2 3 1 
    1 5 5
    

    Sample Output

    3

    Source


    i-A,i-B,I-C :表示i在第(A,B,C)类。

    同一组:表示若1个组员成立,组员全成立


    则可分别维护i在A,B,C组的情况。

    i,j 同类:i-A=j-A,i-B=j-B,I-C=j-C

    i吃j      :i-A=j-B,i-B=j-C,I-C=j-A

    推断   :若i-A和j-B同类,则必有i吃j,否则无法确定(或因为其他连线不可能实现)。以此类推。


    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<functional>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<ctime>
    using namespace std;
    #define For(i,n) for(int i=1;i<=n;i++)
    #define Fork(i,k,n) for(int i=k;i<=n;i++)
    #define Rep(i,n) for(int i=0;i<n;i++)
    #define ForD(i,n) for(int i=n;i;i--)
    #define RepD(i,n) for(int i=n;i>=0;i--)
    #define Forp(x) for(int p=pre[x];p;p=next[p])
    #define Lson (x<<1)
    #define Rson ((x<<1)+1)
    #define MEM(a) memset(a,0,sizeof(a));
    #define MEMI(a) memset(a,127,sizeof(a));
    #define MEMi(a) memset(a,128,sizeof(a));
    #define INF (2139062143)
    #define F (100000007)
    #define MAXN (3*50000+10)
    #define MAXM (100000+10)
    
    long long mul(long long a,long long b){return (a*b)%F;}
    long long add(long long a,long long b){return (a+b)%F;}
    long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
    typedef long long ll;
    class bingchaji
    {
    public:
    	int father[MAXN],n;
    	void mem(int _n)
    	{
    		n=_n;
    		For(i,n) father[i]=i;
    	}
    	int getfather(int x) 
    	{
    		if (father[x]==x) return x;
    		
    		return father[x]=getfather(father[x]);
    	}
    	void unite(int x,int y)
    	{
    		father[x]=getfather(father[x]);
    		father[y]=getfather(father[y]);
    		father[father[x]]=father[father[y]];
    	}
    	bool same(int x,int y)
    	{
    		return getfather(x)==getfather(y);
    	}
    }S;
    
    int main()
    {
    //	freopen("poj1182_template.in","r",stdin);
    //	freopen(".out","w",stdout);
    	int n,m;
    	scanf("%d%d",&n,&m);
    	S.mem(n*3);
    	int ans=0;
    	For(i,m)
    	{
    		int d,x,y;
    		scanf("%d%d%d",&d,&x,&y);
    		if (x>n||y>n||x<1||y<1) {ans++;continue;}
    		if (d==1) 
    		{
    			if (S.same(x,y+n)||S.same(x,y+2*n)) ans++;
    			else 
    			{
    				S.unite(x,y);S.unite(x+n,y+n);S.unite(x+2*n,y+2*n);
    			}
    		}
    		else
    		{
    			if (S.same(x,y)||S.same(x,y+2*n)) ans++;
    			else 
    			{
    				S.unite(x,y+n);S.unite(x+n,y+2*n);S.unite(x+2*n,y);
    			}
    			
    		}
    	}
    	cout<<ans<<endl;
    	
    	return 0;
    }
    



  • 相关阅读:
    我的游戏学习日志30——(对)游戏性的分析(4)
    我的游戏学习日志29——(对)游戏性的分析(3)
    我的游戏学习日志28——(对)游戏性的分析(2)
    我的游戏学习日志27——(对)游戏性的分析(1)
    我的游戏学习日志26——游戏的基础(4)
    我的游戏学习日志25——游戏的基础(3)
    我的游戏学习日志24——游戏的基础(2)
    我的游戏学习日志23——游戏的基础(1)
    在已有Win7/10系统电脑中加装Ubuntu18.04(安装双系统)
    pixhawk入门
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4296531.html
Copyright © 2020-2023  润新知