九度1526

题目链接http://ac.jobdu.com/status.php?user_id=%E8%8F%9C%E9%B8%9F%E9%A3%9E%E5%95%8A%E9%A3%9E

此题据说归类为并查集问题代码为:

#include <iostream>
using namespace std;
int par[100010];


int finPar(int a)
{
 if(par[a] == a)return a;
 else return par[a] = finPar(par[a]);
}


bool uni(int a,int b)
{
 int a1 = finPar(a);
 int b1 = finPar(b);
 if(a1 != b1)
 {


 //cout<<a1<<" "<<b1<<endl;
 if(a1 > b1)par[a1] = b1;
 else par[b1] = a1;
 return true;
 }
 return false;
}


int main()
{
 int m, n;
 int a, b;
 while(cin>>n && n != 0 && cin>>m)
 {
 for(int i = 1;i <= n;i++)
 {
 par[i] = i;
 }
 int cou = n;
 for(int i = 0;i < m;i++)
 {
 cin>>a>>b;
 //if(a > b)par[a] = b;
 //else par[b] = a;
 if(uni(a, b))cou--;
 }
 cout<<cou<<endl;
 }
 return 0;
}

 
 
 
 

 

 
 
  
  
  
  

现在来谈谈具体思路,并查集问题如果直接画图则会看上去很简单,但是这个时候有要选择数据结构的问题,根据纸上画的图那么这样建立数据结构呢,其实只需要一个值去存储这个点属于哪个数据集,这里用的就是par进行标记的,开始时各个点都是分散的,这时每个点为一个独立的标志,当输入a和b时就需要判断a和b是否是同一集合,这时用的方法是finPar,这个方法,当然此时要用到递归。如果这两个数属于同一集合这不需要合并,如果是不同的集合这需要合并

你可能感兴趣的:(九度,1526)