最小生成树模板题 -- Jungle Roads POJ - 1251

Jungle Roads POJ - 1251

题意:
有n个村庄由一些道路连接,每条道路有维护成本,求任意村庄两两相连时所需的最小维护成本。

input
输入包括多组数据,最多100组,最后以输入0表示结束。
对于每一组数据,第一行一个n,表示景区数量。1<n<27
之后n-1行,每行第一个是一个大写字母,表示当前村庄的编号,接着是k,表示当前景区对外可以有k中线路制造方式,接着k对,每对第一个是一个字母,表示这条路线连接的村庄,第二个是一个数字,表示制造成本。0<=k<=15。最多75条制造线路,每条线路的制造成本最大是100。

Output
对于每一组数据,输出一行表示最小成本。

kruskal算法


#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e3+ 5;
int head[maxn], vi[maxn], weight[maxn], next[maxn];
int cnt, dis[maxn], vis[maxn];

void add(int u, int v, int w){
	vi[++cnt] = v;
	weight[cnt] = w;
	next[cnt] = head[u];
	head[u] = cnt;
}

int kruskal(int n){
	int k;
	for(int i = 1; i <= n; i++)
	dis[i] = inf, vis[i] = 0;
	for(int i = 0; i <= n; i++){
		k = - 1;
		for(int j = 1; j <= n; j++)
		if(!vis[j] && (dis[j] < dis[k] || k == -1)) k = j;
		
		if(k == - 1) break;
		
		vis[k] = 1;
		if(i == 0) dis[k] = 0;
		for(int j = head[k]; j; j = next[j]) 
		if(weight[j] < dis[vi[j]] && !vis[vi[j]]) dis[vi[j]] = weight[j];
	}
	int ans = 0;
	for(int i = 1; i <= n; i++)
	ans += dis[i];
	 
	return ans;
}

int main(){
	ios::sync_with_stdio(false);
    int n, u, v, w, k;
    char ch;
    while(cin>>n){
    	if(n == 0) break;
    	
    	cnt = 0;
    	for(int i = 1; i <= n; i++)
    	head[i] = 0;
    	
    	for(int i = 1; i < n; i++){
    		cin >> ch >> k;
    		u = ch - 'A' + 1;
    		for(int j = 0; j < k; j++){
    			cin >> ch >> w;
    			v = ch - 'A' + 1;
    			add(u, v, w);
    			add(v, u, w);
			}
    				
		}
		
    	cout << kruskal(n) <<endl;
	} 
	
}

prim算法

#include<iostream>
#include<algorithm> 
using namespace std;
const int maxn = 1e3 + 5;
struct node{
	int u, v, w;
}edge[maxn];
bool cmp(node a, node b){
	return a.w < b.w;
}

int f[maxn];
int find(int x){
	return x == f[x] ? x : (f[x] = find(f[x]));
} 
int main(){
	ios::sync_with_stdio(false);
	
	int cnt;
	int n, k, u, v, w;
	char ch;
	while(cin >> n){
		if(n == 0) break;
 		for(int i = 0; i <= n; i++) f[i] = i;
		cnt = 0;
		
		for(int i = 1; i < n; i++){
			cin >> ch >> k;
			u = ch - 'A' + 1;
			while(k--){
			   cin >> ch >> w;
			   v = ch - 'A' + 1;
			   edge[++cnt].u = u;
			   edge[cnt].v = v;
			   edge[cnt].w = w;		
			}
		}
		
		sort(edge + 1, edge + 1 + cnt, cmp);
		
		int ans = 0;
		int cot = 0;
		for(int i = 1; i <= cnt; i++)
		{
			
			int fu = find(edge[i].u);
			int fv = find(edge[i].v);
			if(fu != fv) {
				ans += edge[i].w;
				 f[fu] = fv;
				 cot++;
				 	
			}
			if(cot == n - 1) break;
		}
		
		cout << ans <<endl;
	}

	return 0;
	
}
发布了92 篇原创文章 · 获赞 7 · 访问量 3731

猜你喜欢

转载自blog.csdn.net/dajiangyou123456/article/details/104379170
今日推荐