zoukankan      html  css  js  c++  java
  • POJ 1703 Find them, Catch them(并查集高级应用)

    手动博客搬家:本文发表于20170805 21:25:49, 原地址https://blog.csdn.net/suncongbo/article/details/76735893

    URL: http://poj.org/problem?id=1703

    题目大意:本题即很经典的“龙帮虎帮”问题。
    有n个元素(n<=1e5),分布在两个不同的集合里。
    现在有M个语句(m<=1e5),每个语句共两种:(1) 给定某两个元素在不同的集合中。(2) 询问两个元素是否在同一集合中。对于是、否、无法确定的情况,分别输出"In the same gang.", "In different gangs.", "Not sure yet."
    思路分析:假如给定的是两个元素在同一集合中,思路就很明确了。
    但是现在给定的是两个元素不同集合,而且已知仅有两个集合,于是我们就可以想办法将其转化为两元素同集合问题。
    设有元素A,B, 则我们将每个元素分别“克隆”为A', B', 但将她们放入分别与本身不同的另外一个集合中。
    同时,保证A和A', B和B', ..., 永远不会同集合。
    然后,假如已知A与B不同集合,则需将A和B', B和A'分别放入同一集合(union操作),假如已知A与B同集合,则需把A和B, A'和B'进行union一下即可。
    最后,回答询问时,有以下三种情况:
    (1) A与B同集合,或A'与B‘同集合:In the same gang.
    (2) A与B'同集合,或B与A'同集合:In different gangs.
    (3) 其他:Not sure yet.
    代码呈现:(Time:532MS ,Memory:960K ,Code:1005B)

    #include<cstdio>
    using namespace std;
    
    const int MAXN = 1e5;
    int fa[MAXN*2+2];
    int n,m;
    
    int find_fa(int u)
    {
        int i,j,k;
        
        i = u;
        while(fa[i] != i)
        {
            i = fa[i];
        }
    	fa[u] = i;
    	j = u;
    	while(j != i)
    	{
    		k = fa[j];
    		fa[j] = i;
    		j = k;
    	}
        return i;
    }
    
    int main()
    {
    	int i,t,p,q,pp,qq,x,y;
    	char ch[3];
    	
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d%d",&n,&m);
    		for(i=1; i<=2*n; i++) //Union-Find Sets init
    		{
    			fa[i] = i;
    		}
    		for(i=1; i<=m; i++) //calculate while reading
    		{
    			scanf("%s%d%d",ch,&x,&y);
    			if(ch[0] == 'A')
    			{
    				p = find_fa(x);
    				q = find_fa(y);
    				pp = find_fa(x+n);
    				qq = find_fa(y+n);
    				if(p == q) printf("In the same gang.\n");
    				else if(pp == q || p == qq) printf("In different gangs.\n");
    				else printf("Not sure yet.\n");
    			}
    			else if(ch[0] == 'D')
    			{
    				p = find_fa(x);
    				q = find_fa(y);
    				pp = find_fa(x+n);
    				qq = find_fa(y+n);
    				if(pp != q) fa[pp] = q;
    				if(qq != p) fa[qq] = p;
    			}
    		}
    	}
    	
    	return 0;
    }
    

    类似题目:poj 2492 A Bug's Life (几乎一模一样)
    poj 1182 && luogu P2024 [NOI 2001]食物链 (一样的思路,元素分成三类)
    luogu P1525 [NOIP 2010提高组] 关押罪犯 (个人认为难度较大)

  • 相关阅读:
    .net Core 使用AutoMapper
    文件批量生成IO流读写
    .net Core数据的幕等性
    .net core 拦截器的使用
    墙上你APP设计与实现
    H5 App实现热更新,不需要重新安装app
    支付宝支付接口的使用详细说明
    .net 数据源DataSet 转换成模型
    .net ajax跨域请求问题
    【系统之音】SystemUI篇(二)SysytemUI功能一览--草稿
  • 原文地址:https://www.cnblogs.com/suncongbo/p/10182082.html
Copyright © 2011-2022 走看看