GitBook

这里写图片描述 这里写图片描述

基础的最小生成树题目 可以拿来练习一下Prim算法和Kruskal算法的运用

Prim:

#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
	int dis[120];
	int e[120][120];
	bool flag[120];
	int N,inf=999999;
	while(scanf("%d",&N),N) {
		for(int i=1; i<=N; i++) {
			dis[i]=inf;
			flag[i]=false;
		}
		for(int i=1; i<=N; i++) {
			for(int j=1; j<=N; j++) {
				e[i][j]=inf;
			}
		}
		int T=N*(N-1)/2;
		while(T--) {
			int n,m,t;
			scanf("%d %d %d",&n,&m,&t);
			e[n][m]=t;
			e[m][n]=t;
		}
		int sum=0;
		dis[1]=0;
		while(true) {
			int v=-1;
			for(int u=1; u<=N; u++) {
				if(!flag[u]&&(v==-1||dis[u]<dis[v]))
					v=u;
			}
			if(v==-1)
				break;
			flag[v]=true;
			sum+=dis[v];
			for(int u=1; u<=N; u++) {
				dis[u]=min(dis[u],e[v][u]);
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}

Kruskal:

有个小插曲就是这次用了这一句 using namespace std; 导致了 rank 这个数组出错了 应该是命名重名那方面的原因…… 虽然本地调试并没问题 然后改了个名字 也是AC了

#include<stdio.h>
#include<algorithm>
using namespace std;

struct edge {
	int u,v,dis;
} e[14400];

int par[120];
int ran[120];

int find(int m) {
	if(m==par[m])
		return m;
	else
		return par[m]=find(par[m]);
}
void unite(int x,int y) {
	x=find(x);
	y=find(y);
	if(x==y)
		return;
	if(ran[x]<ran[y])
		par[x]=y;
	else {
		par[y]=x;
		if(ran[x]==ran[y])
			ran[x]++;
	}
}
bool cmp(edge A,edge B) {
	return A.dis<B.dis;
}
int main() {
	int N;
	while(scanf("%d",&N),N) {
		for(int i=1; i<=N; i++) {
			par[i]=i;
			ran[i]=0;
		}
		int T=N*(N-1)/2;
		for(int i=0; i<T; i++) {
			scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].dis);
		}
		sort(e,e+T,cmp);
		int sum=0;
		for(int i=0; i<T; i++) {
			if(find(e[i].u)!=find(e[i].v)) {
				sum+=e[i].dis;
				unite(e[i].u,e[i].v);
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}

题目地址:【杭电】[1233]还是畅通工程