zoukankan      html  css  js  c++  java
  • 51nod 1515:明辨是非 并查集合并

    题目来源: 原创
    基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
     收藏
     关注

    给n组操作,每组操作形式为x y p。

    当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。

    当p为0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。

    Input
    输入一个数n表示操作的次数(n<=1*10^5)
    接下来n行每行三个数x,y,p(x,y<=1*10^8,p=0 or 1)
    Output
    对于n行操作,分别输出n行YES或者NO
    Input示例
    3
    1 2 1
    1 3 1
    2 3 0
    Output示例
    YES
    YES
    NO

    考虑用并查集维护相等关系,用set维护不等关系。
    就是说相等的放在一个并查集里面,这个集合开个set,其中存放和它不等的并查集序号。
    如果限制不相等,显然就是在set中添加元素
    如果限制相等,那么我们可以通过启发式合并将两个并查集以及他们对应的set合并
    复杂度为n*(logn)^2

    代码:

    #include <iostream>  
    #include <algorithm>  
    #include <cmath>  
    #include <vector>  
    #include <string>  
    #include <cstring>
    #include <set>
    #include <map>
    #pragma warning(disable:4996)  
    using namespace std;
    
    int pre[200005];
    int x[100005];
    int y[100005];
    int oper[100005];
    int num[200005];
    set<int> notequal[50005];
    int n,m,shizu1,shizu2;  
    set<int>::iterator it1,it2;
    map<int,int>hash_m;
    
    int findpre(int x)  
    {  
    	while(x!=pre[x])  
    	{  
    		x=pre[x];  
    	}  
    	return x;  
    }  
    
    void union_set(int x,int y)  
    {  
    	int pre_x = x;  
    	int pre_y = y;  
    
    	if(pre_x == pre_y)  
    		return;  
    	else if(notequal[pre_y].size()>notequal[pre_x].size())  
    	{  
    		int temp = pre_x;  
    		pre_x = pre_y;  
    		pre_y = temp;  
    	}  
    
    	pre[pre_y]=pre_x;  
    
    	for(it2=notequal[pre_y].begin();it2!=notequal[pre_y].end();it2++)
    	{
    		notequal[pre_x].insert(*it2);
    	}
    }  
    
    template <class F,class T>
    F bin_search(F s,F e,T val)
    {
    	F L = s;
    	F R = e-1;
    
    	while(L<=R)
    	{
    		F mid = L + (R-L)/2;
    		if(!(*mid<val || val < *mid))
    		{
    			return mid;
    		}
    		else if(val < *mid)
    		{
    			R = mid -1;
    		}
    		else
    		{
    			L= mid + 1;
    		}
    	}
    }
    
    int main()
    {
    	//freopen("i.txt","r",stdin);
    	//freopen("o.txt","w",stdout);
    
    	int i,j,test,num_m,le,re;
    	num_m=0;
    	scanf("%d",&test);
    	for(j=1;j<=test;j++)
    	{
    		scanf("%d%d%d",&x[j],&y[j],&oper[j]);
    		num[num_m]=x[j];
    		pre[num_m]=num_m;
    		num_m++;
    
    		num[num_m]=y[j];
    		pre[num_m]=num_m;
    		num_m++;
    	}
    	sort(num,num+num_m);
    	num_m=unique(num,num+num_m)-num;
    	for(j=0;j<num_m;j++)
    	{
    		hash_m[num[j]]=j;
    	}
    	for(j=1;j<=test;j++)
    	{
    		le=hash_m[x[j]];
    		re=hash_m[y[j]];
    		shizu1=findpre(re);
    		shizu2=findpre(le);
    		if(oper[j]==1)
    		{
    			int flag=0;
    
    			if(notequal[shizu2].size()<notequal[shizu1].size())
    			{
    				it1=notequal[shizu2].find(shizu1);
    				if(it1!=notequal[shizu2].end())    //找到
    				{
    					flag=1;
    				}
    				if(flag==0)
    				{
    					for(it1=notequal[shizu2].begin();it1!=notequal[shizu2].end();it1++)
    					{
    						if(shizu1 == findpre(*it1))
    						{
    							flag=1;
    							break;
    						}
    					}
    				}
    			}
    			else
    			{
    				it2=notequal[shizu1].find(shizu2);
    				if(it2!=notequal[shizu1].end())    //找到
    				{
    					flag=1;
    				}
    				for(it2=notequal[shizu1].begin();it2!=notequal[shizu1].end();it2++)
    				{
    					if(shizu2 == findpre(*it2))
    					{
    						flag=1;
    						break;
    					}
    				}
    			}
    
    			if(flag==0)       
    			{
    				union_set(shizu1,shizu2);
    				printf("YES
    ");
    			}
    			else
    			{
    				printf("NO
    ");
    			}
    		}
    		else
    		{
    			if(shizu1==shizu2)
    			{
    				printf("NO
    ");
    			}
    			else
    			{
    				notequal[shizu2].insert(shizu1);
    				notequal[shizu1].insert(shizu2);
    				printf("YES
    ");
    			}
    		}
    	}
    	//system("pause");
    	return 0;
    }





    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    遗产继承骗局
    Nginx配置https和wss
    Servlet乱码问题
    logback+slf4j作为日志系统
    InteliJ Idea通过maven创建webapp
    pip安装注意事项
    [转]TCP(HTTP)长连接和短连接区别和怎样维护长连接
    Python Socket编程初探
    有用的git片段
    Python使用chardet包自动检测编码
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4899518.html
Copyright © 2011-2022 走看看