今天学习的最小生成树。最小生成树算法包括Kruskal 算法和prim 算法。其中一个算法是将两点之间的连线大小从小到大排。并判断其是否在一个集合中,如果不是一个集合中将其从小到大连起来。直到它等于点的个数减一则形成了一个最小生成树。另一种算法就较为复杂。他首先将一个点放入集合中,然后依次判断其他点与它的年限距离,选取最小的,并将连线的另一个点也放入集合,然后再将没有放入集合的点与放入集合的点的距离进行判断,在选择最小的,依次选择直至形成一颗最小生成树。另外在两种算法的学习之中,我学到了一个排序的函数。sort(a + 1, a + 1 + m, cmp);在这个函数中,Sort是排序的意思,a+1是指集合中的第一个元素,a+1+m 是指集合中的最后一个元素,cmp 是另一个函数表示升序排列即为bool cmp(point a, point b) {
return a.t < b.t;
}
若将大小符号反转,则为降序
另外今天还写了一个题目
P3366 【模板】最小生成树
# 【模板】最小生成树
## 题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 `orz`。
## 输入格式
第一行包含两个整数 $N,M$,表示该图共有 $N$ 个结点和 $M$ 条无向边。
接下来 $M$ 行每行包含三个整数 $X_i,Y_i,Z_i$,表示有一条长度为 $Z_i$ 的无向边连接结点 $X_i,Y_i$。
## 输出格式
如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 `orz`。
## 样例 #1
### 样例输入 #1
```
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
```
### 样例输出 #1
```
7
```
## 提示
数据规模:
对于 $20\%$ 的数据,$N\le 5$,$M\le 20$。
对于 $40\%$ 的数据,$N\le 50$,$M\le 2500$。
对于 $70\%$ 的数据,$N\le 500$,$M\le 10^4$。
对于 $100\%$ 的数据:$1\le N\le 5000$,$1\le M\le 2\times 10^5$,$1\le Z_i \le 10^4$。
样例解释:
![](https://cdn.luogu.com.cn/upload/pic/2259.png)
所以最小生成树的总边权为 $2+2+3=7$。
代码
#include<bits/stdc++.h>
using namespace std;
using std::sort;
int fa[5005];
struct point{
int x,y,t;
}a[200005];
bool cmp(point a, point b) {
return a.t < b.t;
}
void init(int d){
for(int i=1;i<=d;i++){
fa[i]=i;
}
}
int find(int i){
if(fa[i]==i){
return i;
}
else{
fa[i]=find(fa[i]);
return fa[i];
}
}
int main(){
int n,m;
long long sum=0;
cin>>n>>m;
init(n);
for(int i=1;i<=m;i++){
cin>>a[i].x>>a[i].y>>a[i].t;
}
sort(a + 1, a + 1 + m, cmp);
for (int i = 1; i <= m; i++) {
if (find(a[i].x) != find(a[i].y))
{
fa[a[i].y]=a[i].x;
sum += a[i].t;
n--;
}
if (n == 1)
{
cout << sum;
return 0;
}
}
cout << "orz";
return 0;
}
每天进步一点点,加油!