추신 : 스테이션 B에 대한 설명
Kruskal 알고리즘 의 기본 아이디어는 처음에는 모든 모서리를 숨기고 그래프의 각 정점이 자체적으로 연결된 블록이되도록하는 것입니다. 그런 다음 다음 단계를 수행하십시오.
- 가장 작은 것부터 가장 큰 것까지 모든 모서리를 정렬합니다.
- 작은 것부터 큰 것까지 가장자리 가중치에 따라 모든 가장자리를 테스트합니다. 현재 테스트 된 가장자리로 연결된 두 정점이 연결된 블록에 없으면이 테스트 가장자리를 현재 최소 스패닝 트리에 추가하고 그렇지 않으면 가장자리를 버립니다.
- 최소 스패닝 트리의 가장자리 수가 총 정점 수에서 1을 뺀 값보다 적거나 모든 가장자리에 대한 테스트가 끝날 때까지 2 단계를 수행합니다. 최소 스패닝 트리의 간선 수가 총 정점 수에서 끝을 뺀 값보다 적 으면 그래프가 연결되지 않습니다.
주형:
struct node{
//存储边及边权
int u,v,dis;
}e[M];
bool cmp(node x,node y){
//sort的比较函数
return x.dis < y.dis;
}
int father[N]; //存放每个节点的父亲节点的father数组
int findfather(int v){
//查找节点的父亲节点
if(father[v] == v) return v;
else{
int F = findfather(father[v]);
father[v] = F;
return F;
}
}
int Kruskal(int n,int m){
int ans = 0,num_edge = 0;
//ans为所求最小生成树的边权之和,num_edge为当前生成树的边数
for(int i = 0;i< n;i++){
//father[]初始化,注意节点的范围(以0 - n为例)
father[i] = i;
}
sort(e,e+m,cmp); //对边的权值按照从小到大排序
for(int i = 0;i< m;i++){
int fu = findfather(e[i].u);
int fv = findfather(e[i].v);
if(fu != fv){
//如果两个节点的父亲节点不同,则将次边加入最小生成树
ans+= e]i].dis; //加上边权
father[fu] = fv;
num_edge++;
if(num_edge == n-1) //如果最小生成树的边数目达到节点数减一,就退出
break;
}
}
return ans;
}
시작하다:
6 10
0 1 4
0 4 1
0 5 2
1 2 6
1 5 3
2 3 6
2 5 5
3 4 4
3 5 5
4 5 3
첫 번째 줄은 정점 수와 가장자리 수이고
다음 m 줄은 두 노드의 출력과 노드 간 가장자리 가중치입니다
.
15
암호:
#include<bits/stdc++.h>
using namespace std;
int n,m,father[100];
struct node{
//边的两个顶点和边权
int u,v,dis;
}e[100];
bool cmp(node x,node y){
//sort函数的比较函数
return x.dis<y.dis;
}
int findf(int v){
//并查集的寻找函数
if(father[v] == v) return v;
else{
int F = findf(father[v]); //注意这里函数的参数是father[v]
father[v] = F;
return F;
}
}
int Kruskal(){
int re = 0,num_edge = 0;
//re为边权之和,num_edge为目前生成树中的边
for(int i = 0;i<n;i++){
//father数组初始化
father[i] = i;
}
sort(e,e+m,cmp); //对边从小到大排序
for(int i = 0;i<m;i++){
int fu = findf(e[i].u); //找到父亲节点
int fv = findf(e[i].v);
if(fv != fu){
re += e[i].dis;
father[fu] = fv;
num_edge++;
if(num_edge == n - 1 ) //如果边的数量达到了生成树的最大边数
break;
}
}
return re;
}
int main(){
freopen("a.txt","r",stdin);
int u,v,k;
cin>>n>>m;
for(int i = 0;i<m;i++){
//读入数据
cin>>u>>v>>k;
e[i].u = u;
e[i].v = v;
e[i].dis = k;
}
cout<<Kruskal()<<endl;
return 0;
}
종료.