最小生成树——并查集
简单模板题-洛谷3367并查集
题目描述
如题,现在有一个并查集,你需要完成合并和查询操作。
输入格式
第一行包含两个整数 N,MN,M ,表示共有 NN 个元素和 MM 个操作。
接下来 MM 行,每行包含三个整数 Z_i,X_i,Y_iZ**i,X**i,Y**i 。
当 Z_i=1Z**i=1 时,将 X_iX**i 与 Y_iY**i 所在的集合合并。
当 Z_i=2Z**i=2 时,输出 X_iX**i 与 Y_iY**i 是否在同一集合内,是的输出 Y
;否则输出 N
。
输出格式
对于每一个 Z_i=2Z**i=2 的操作,都有一行输出,每行包含一个大写字母,为 Y
或者 N
。
输入输出样例
输入 #1复制
4 7
2 1 2
1 1 2
2 1 2
1 3 4
2 1 4
1 2 3
2 1 4
输出 #1复制
N
Y
N
Y
说明/提示
对于 30%30% 的数据,N \le 10N≤10,M \le 20M≤20。
对于 70%70% 的数据,N \le 100N≤100,M \le 10^3M≤103。
对于 100%100% 的数据,1\le N \le 10^41≤N≤104,1\le M \le 2\times 10^51≤M≤2×105,1 \le X_i, Y_i \le N1≤X**i,Y**i≤N,Z_i \in { 1, 2 }Z**i∈{1,2}。
#include <bits/stdc++.h>
using namespace std;
int n,m,z,x,y;
int father[10005];
int find(int point)
{
if(father[point]==point)
return point;
return father[point]=find(father[point]);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
father[i]=i;
for(int i=0;i<m;i++)
{
cin>>z>>x>>y;
x=find(x);
y=find(y);
if(z==1)
{
if(x!=y)
father[x]=y;
}
else {
if(x==y)
cout<<"Y\n";
else
cout<<"N\n";
}
}
return 0;
}
进阶一点点的并查集的题,洛谷——口袋的天空
题目背景
小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空。
有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖。
题目描述
给你云朵的个数 NN,再给你 MM 个关系,表示哪些云朵可以连在一起。
现在小杉要把所有云朵连成 KK 个棉花糖,一个棉花糖最少要用掉一朵云,小杉想知道他怎么连,花费的代价最小。
输入格式
第一行有三个数 N,M,KN,M,K。
接下来 MM 行每行三个数 X,Y,LX,Y,L,表示XX云和 YY 云可以通过 LL 的代价连在一起。
输出格式
对每组数据输出一行,仅有一个整数,表示最小的代价。
如果怎么连都连不出 KK 个棉花糖,请输出 No Answer
。
输入输出样例
输入 #1复制
3 1 2
1 2 1
输出 #1复制
1
说明/提示
对于 30%30% 的数据,N \le 100N≤100,M \le 10^3M≤103;
对于 100%100% 的数据,1 \le N \le 10^31≤N≤103,1 \le M \le 10^41≤M≤104,1 \le K \le 101≤K≤10,1 \le X,Y \le N1≤X,Y≤N,0 \le L<10^40≤L<104。
#include <bits/stdc++.h>
using namespace std;
int n,m,k,l,x,y;
int father[10005];
int now=0,need=0;//记录合并了多少次,需要合并多少次
int all=0;//记录最小生成树各边之和
struct edge{
int from,to,wage;
};
edge e[10005];
bool cmp(edge a,edge b)
{
return a.wage<b.wage;
}
int find(int point)
{
if(father[point]==point)
return point;
return father[point]=find(father[point]);
}
int main()
{
cin>>n>>m>>k;
need=n-k;
for(int i=1;i<=n;i++)
father[i]=i;
for(int i=1;i<=m;i++)
{
cin>>e[i].from>>e[i].to>>e[i].wage ;
}
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;++i)
{
x=find(e[i].from);
y=find(e[i].to );
if(x!=y)
father[x]=y,++now,all+=e[i].wage ;
if(now==need)
{
cout<<all;
return 0;
}
}
cout<<"No,Answer";
return 0;
}