数据结构与算法实验题 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; }
由于查询次数较少 不压缩路径可能还会 快一些