zoukankan      html  css  js  c++  java
  • 并查集

    首先什么是并查集:

           并查集(Union Find)是一种用于管理分组的数据结构。它具备两个操作:(1)查询元素a和元素b是否为同一组   (2) 将元素a和b合并为同一组。

    并查集的学习:

    https://blog.csdn.net/luomingjun12315/article/details/47373345

    http://acm.hdu.edu.cn/showproblem.php?pid=1213

    #include<iostream>
    using namespace std;
    int node[1050];
    int deep[1050];
    int sum;
    void Init(int n)
    {
    	for(int i=1;i<=n;i++)
    	{
    		node[i]=i;
    		deep[i]=0;
    	}
    }
    int Find(int x)
    {
    	if(x==node[x])
    	return x;
    	return node[x]=Find(node[x]);
    }
    void Union(int x,int y)
    {
    	x=Find(x);
    	y=Find(y);
    	if(x==y)
    	return ;
    	sum--;
    	if(deep[x]<deep[y])
    	node[x]=y;
    	else
    	{
    		node[y]=x;
    		if(deep[x]==deep[y])
    		deep[x]++;
    	}
    }
    int main()
    {
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		int n,m;
    		cin>>n>>m;
    		sum=n;
    		Init(n);
    		for(int i=1;i<=m;i++)
    		{
    			int x,y;
    			cin>>x>>y;
    			Union(x,y);
    		}
    		cout<<sum<<endl;
    	}
    	return 0;
    }
    

      

    http://poj.org/problem?id=1611

    #include<iostream>
    using namespace std;
    int node[30050],deep[30050],num[30050];
    void Init(int n)
    {
    	for(int i=0;i<n;i++)
    	{
    		node[i]=i;
    		deep[i]=0;
    		num[i]=1;
    	}
    }
    int Find(int x)
    {
    	if(x==node[x])
    	return x;
    	return node[x]=Find(node[x]);
    }
    void Union(int x,int y)
    {
    	x=Find(x);
    	y=Find(y);
    	if(x==y)
    	return ;
    	if(deep[x]<deep[y])
    	{
    		node[x]=y;
    		num[y]+=num[x];
    	}
    	else
    	{
    		node[y]=x;
    		num[x]+=num[y];
    		if(deep[y]==deep[x])
    		deep[x]++;
    	}
    }
    int main()
    {
    	int n,m;
    	while(cin>>n>>m)
    	{
    		if(n==0&&m==0)
    		break;
    		Init(n);
    		while(m--)
    		{
    			int t,x,y;
    			cin>>t;
    			cin>>x;
    			for(int i=1;i<t;i++)
    			{
    				cin>>y;
    				Union(x,y);
    				x=y;
    			}
    		}
    		int ans=Find(0);
    		cout<<num[ans]<<endl;
    	}
    	return 0;
    }
    

      

    http://poj.org/problem?id=2236

    #include<iostream>
    #include<cstring>
    using namespace std;
    int node[1050],xy[1050][2],deep[1050];
    bool vis[1050];//注意遍历的使用
    void Init(int n)
    {
    	for(int i=1;i<=n;i++)
    	{
    		node[i]=i;
    		deep[i]=0;
    	}
    }
    int Find(int x)
    {
    	if(x==node[x])
    	return x;
    	else 
    	return node[x]=Find(node[x]);
    }
    void Union(int m,int n,int d)
    {
    	for(int i=1;i<=n;i++)
    	{
    		if(vis[i]&&((xy[i][0]-xy[m][0])*(xy[i][0]-xy[m][0])+(xy[i][1]-xy[m][1])*(xy[i][1]-xy[m][1]))<=d*d)
    		{
    			int x=Find(i);
    			int y=Find(m);
    			if(x==y)
    			continue;
    			if(deep[x]<deep[y])
    			{
    				node[x]=y;
    			}
    			else
    			{
    				node[y]=x;
    				if(deep[x]==deep[y])
    				deep[x]++;
    			}
    		}
    	}
    }
    int main()
    {
    	int n,d,m,p;
    	while(cin>>n>>d)
    	{
    		Init(n);
    		memset(vis,false,sizeof(vis));
    		char s;
    		for(int i=1;i<=n;i++)
    		{
    			cin>>xy[i][0]>>xy[i][1];
    		}
    	//	getchar();
    		while(cin>>s)
    		{
    			if(s=='O')
    			{
    				cin>>m;
    			//	getchar();
    				vis[m]=true;
    				Union(m,n,d);
    			}
    			else
    			{
    				cin>>m>>p;
    			//	getchar();
    				if(vis[m]&&vis[p]&&Find(m)==Find(p))
    				cout<<"SUCCESS"<<endl;
    				else
    				cout<<"FAIL"<<endl;
    			}
    		}
    	}
    	return 0;
    }
    

      

    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    模板汇总 —— 杨式图表
    HDU 6634 网络流最小割模型 启发式合并
    网络流 从0开始学建图
    分层图 单调决策性DP
    模板汇总——笛卡尔树
    Bzoj 2127 happiness 最小割
    manacher --- 暂 旧版本
    Bzoj 3730 震波 动态点分治
    HDU
    Maven私服(Repository Manager)
  • 原文地址:https://www.cnblogs.com/caijiaming/p/9102085.html
Copyright © 2011-2022 走看看