数据结构与算法实验题 9.7 多彩塔

数据结构与算法实验题 9.7 多彩塔

★实验任务

芒果冰沙准备画一座多彩塔,这座塔一共有N 层,每层为一种颜色,当然有些层颜色会相同。颜色具有传递关系:如果第 a 层和第 b层同色,并且第 a 层和第 c 层同色,那么第 b层和第 c 层也同色。

七彩塔要从第 1层开始画,如果要画第 i 层,那么 i 层之前必须都要画完,因为如果前面的没画完就不知道在哪个位置画第 i 层。同一时刻,芒果冰沙手中最多拿一种颜色的笔,最初他手中拿着画第一层颜色的笔

现在给出了某些层的颜色是相同的,如果不能根据给出的条件推出某两层颜色相同,那么我们就认为他们不相同。他想知道怎样更换最少次数的笔来完成多彩塔的创作。

★数据输入

输入第一行包含两个数 N,M(1<=N<=500000,1<=M<=100000),分别表示这座塔的层数和下面给出相等颜色关系的个数。

接下来有 M 行,每行两个数 a,b(1<=a,b<=N)表示第 a 层和第 b 层的颜色是相同的。

★数据输出

输出最少更换笔的次数。

输入示例1

4 2
1 2
3 4

输出示例1

1

输入示例2

4 2
1 2
1 4

输出示例2

2

并查集题目,题目理解和解答相对简单,有个小技巧就是用now存当前的颜色,减少重复查询
#include<stdio.h>
#include<iostream>
using namespace std;

typedef int elem;
typedef int set;

void Union(int s[],set r1,set r2)
{
    if (r1 == r2)return ;
    if(s[r2]<s[r1])
    {
        s[r2] += s[r1];
        s[r1] = r2;
    }
    else 
    {
        s[r1] += s[r2];
        s[r2] = r1;
    }
}

set find(int s[],elem x){
    if(s[x]<0) return x;
    else return s[x] = find(s,s[x]);
}

int main(){
    int n,m;
    cin>>n>>m;
    int s[n+1];
    for(int i=0;i<=n;i++)s[i]=-1;
    int t1,t2;
    for(int i=0;i<m;i++){
        cin>>t1>>t2;
        Union(s,find(s,t1),find(s,t2));
    }
    int now = find(s,1);
    int cnt = 0;
    int t;
    for(int i=2;i<=n;i++){
        t = find(s,i);
        if(t!=now){
            cnt++;
            now=t;
        }
    }
    cout<<cnt;
    return 0;
}

由于查询次数较少 不压缩路径可能还会 快一些

 

posted on 2020-12-29 20:44  xwwer  阅读(178)  评论(0编辑  收藏  举报