合根植物(蓝桥杯)--并查集的运用

合根植物(蓝桥杯)–并查集的运用
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
  这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
  
  如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?

思路:有n行m列,即共有n*m个植物,他们两两之间可能会有联系,在这里做一个约定,就是右边的追随左边的为boss,当然开始的时候每一个人的boss都是自己,这样到最后只需要观察有多少个boss,就知道有多少株合根植物了。
注:记住“擒贼先擒王”的原则,就是一团的一个人追随了另一个团,那么他们的王就要追随人家。和“压缩路径”,就是帮助找到自己boss的要受到提拔,直接追随总boss。
代码如下:

#include <iostream>
#define maxn 1000000
using namespace std;
int n,m,f[maxn];
void init()
{
    
    
 int i;
 for(i=1;i<=n;i++)
 {
    
    
  f[i]=i;
 }
}
int getf(int x)
{
    
    
 if(f[x]==x)
 {
    
    
  return x;
 }
 else {
    
    
  f[x]=getf(f[x]);
  return f[x];
 }
}
void merge(int v,int u)
{
    
    
 int t1,t2;
 t1=getf(v);//分别寻找两者的boss
 t2=getf(u);
 if(t1!=t2)
 {
    
    
  f[t2]=t1;//两者的boss不是同一个,这里遵循“向左原则”,右边追随左边 
 }
}
int main()
{
    
    
 int i,x,y,sum=0;
 cin>>x>>y;
 n=x*y;
 cin>>m;
 init();//初始化,将n个单独的个体分别设置其追随的boss是自己 
 for(i=1;i<=m;i++)
 {
    
    
  cin>>x>>y;
  merge(x,y);//合并两者 
 }
 for(i=1;i<=n;i++)
 {
    
    
  if(f[i]==i)
  {
    
    
   sum++;
  }
 }
 cout<<endl;
 return 0;
}

猜你喜欢

转载自blog.csdn.net/HT24k/article/details/106267766
今日推荐