1. Questions
Give an example, draw the process of using Prim algorithm to construct the minimum spanning tree, and write the algorithm according to the experimental report template.
Give an example, draw the process of using Kruskal algorithm to construct the minimum spanning tree, and write the algorithm according to the experimental report template.
2. Resolve
in a given undirected graph G = (V, E), (u, v) represents the edge connecting vertex u and vertex v, w(u, v) represents the weight of this edge, if there is T If it is a subset of E and an acyclic graph, so that w(T) is the smallest, then this T is the minimum spanning tree of G.
Prim algorithm:
Suppose the set of points in the minimum spanning tree is U. At the beginning, the minimum spanning tree is empty, so U is empty.
Kruskal algorithm:
Let the set of edges in the minimum spanning tree be T, and the minimum spanning tree is empty at the beginning, so T is empty.
3. Design
Prime:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
#include<iomanip>
#include<map>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<set>
#include<cctype>
#include<string>
#include<stdexcept>
#include<fstream>
#include<sstream>
#include<sstream>
#define mem(a,b) memset(a,b,sizeof(a))
#define debug() puts("what the fuck!")
#define dedebug() puts("what the fuck!!!")
#define ll long long
#define ull unsigned long long
#define speed {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); };
using namespace std;
const double PI = acos(-1.0);
const int maxn = 2e5 + 10;
const int N = 2e3 + 10;
const ll INF = 1e18;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double esp_0 = 1e-6;
const double gold = (1 + sqrt(5)) / 2;
inline int rd() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll quick(ll a, ll b) {
ll ans = 1;
while (b) {
if (b % 2) {
ans = ans * a % mod;
}
b >>= 1;
a = a * a % mod;
}
return ans % mod;
}
ll gcd(ll x, ll y) {
return y ? gcd(y, x % y) : x;
}
int n, m;
int g[110][110];
int dis[110];
int vis[110];
int prim() {
memset(vis, 0, sizeof vis);//标记数组
memset(dis, inf, sizeof dis);//最小生成树节点间距离
dis[1] = 0;
for (int i = 1; i < m; ++i) {
int pos = 0;
for (int j = 1; j <= m; ++j) {
if (!vis[j] && (pos == 0 || dis[j] < dis[pos]))pos = j;
}
vis[pos] = 1;
for (int j = 1; j <= m; ++j) {
if (!vis[j])dis[j] = min(dis[j], g[pos][j]);
}
}
int ans = 0;
for (int i = 1; i <= m; ++i) {
if (dis[i] == inf)return -1;//如果有一个点的dis值为inf,说明该点被孤立,原图不存在最小生成树
ans += dis[i];
}
return ans;//返回权值和
}
signed main() {
scanf("%d%d", &n, &m);
memset(g, inf, sizeof g);
for (int i = 1; i <= n; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
g[u][v] = g[v][u] = w;
}
int ans = prim();
cout << ans << endl;
return 0;
}
kruskal:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
#include<iomanip>
#include<map>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<set>
#include<cctype>
#include<string>
#include<stdexcept>
#include<fstream>
#include<sstream>
#include<sstream>
#define mem(a,b) memset(a,b,sizeof(a))
#define debug() puts("what the fuck!")
#define dedebug() puts("what the fuck!!!")
#define ll long long
#define ull unsigned long long
#define speed {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); };
using namespace std;
const double PI = acos(-1.0);
const int maxn = 2e5 + 10;
const int N = 2e3 + 10;
const ll INF = 1e18;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double esp_0 = 1e-6;
const double gold = (1 + sqrt(5)) / 2;
inline int rd() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
ll quick(ll a, ll b) {
ll ans = 1;
while (b) {
if (b % 2) {
ans = ans * a % mod;
}
b >>= 1;
a = a * a % mod;
}
return ans % mod;
}
ll gcd(ll x, ll y) {
return y ? gcd(y, x % y) : x;
}
struct Edge {
int u, v, w;
Edge() {
};
Edge(int u, int v, int w) :u(u), v(v), w(w) {
};
bool operator<(const Edge& a) {
return w < a.w;
}
}edge[110];
int n, m;
int fa[110];
void init() {
for (int i = 1; i <= m; ++i)fa[i] = i;
}
int find(int x) {
return fa[x] == x ? x : find(fa[x]);
}
int uni(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx != fy) {
fa[fx] = fy;
return 1;
}
return 0;
}
int kruskal() {
int ans = 0;
init();
sort(edge + 1, edge + 1 + n);
for (int i = 1; i <= n; ++i) {
if (uni(edge[i].u, edge[i].v))
ans += edge[i].w;
}
return ans;
}
signed main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
edge[i] = Edge(u, v, w);
}
printf("%d\n", kruskal());
return 0;
}
4. Analyze
prim:
Priority queue optimization is not used, it is necessary to traverse each point O (V2), and accumulate O (V), the total time complexity is O (V2+V), which is about O (V2)
kruskal: Yes The time complexity of edge sorting is about O(Elog2E), and the query set operation is O(E), and the total is O(Elog2E+E), which is about O(Elog2E)