Algorithm analysis and design assignment 1

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.

Insert picture description here
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.

Insert picture description here
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)

5. GitHub source code
prim
kruskal

Guess you like

Origin blog.csdn.net/qq_40924271/article/details/114550970