cpp图算法

复习图的一些算法,使用c++实现

最小生成树(Kruscal)

思路:每次加入最短的边,要求加入后不成环(即两个顶点不连通)。

整个算法分成两部分:一是并查集,判断点的连通性,二是排序之后的选择以及结点连通性的修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

vector<int> fatherList;

struct link{
int start,end,weight;
link(){};
link(int s,int e,int w){
start = s;
end = e;
weight = w;
}
};

bool compare(link l1, link l2){
return l1.weight<l2.weight;
}

int father(int x){
if(fatherList[x]==x)
return x;
return father(fatherList[x]);
}

void combine(int x, int y){
fatherList[father(x)] = father(y);
}

int main(){
int num;
while(cin>>num){
if(num==0)
break;
fatherList.clear();
for(int i=0;i<=num;i++)
fatherList.push_back(i);
int n = num*(num-1)/2;
vector<link> list;
while(n-->0){
int s,e,w;
cin>>s>>e>>w;
link tmp(s,e,w);
list.push_back(tmp);
}
sort(list.begin(),list.end(),compare);
int cnt = 0, sum=0, idx=0;
while(cnt++<num-1){
while(father(list[idx].start)==father(list[idx].end))
idx++;
sum+=list[idx].weight;
combine(list[idx].start,list[idx].end);
idx++;
}
cout<<sum<<endl;
}
return 0;
}

//输入样例
// 3
// 1 2 1
// 1 3 2
// 2 3 4
// 4
// 1 2 1
// 1 3 4
// 1 4 1
// 2 3 3
// 2 4 2
// 3 4 5
// 0
Author: Jiaming Luo
Link: http://wanpiqiu123.github.io/2020/06/27/cpp%E5%9B%BE%E7%AE%97%E6%B3%95/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.