【算法】最小生成树之prim

本文通过三个具体的POJ题目,详细介绍了Prim最小生成树算法的应用。包括如何初始化图、选取最小边构建最小生成树并计算其权重总和。适用于理解与实践Prim算法。

1.prim算法




2.问题


2.1 POJ 1258


源代码
#include "stdio.h"
#include "stdlib.h"
#define MAX 100

int farm[MAX][MAX]={0};

void init(int N)
{
	int i,j;
	for(i=0;i<N;i++) 
		for(j=0;j<N;j++)
			scanf("%d",&farm[i][j]);
}

void prim(int N)
{
	int i,count=1,sum=0,min_node,min_lowcost;
	int *lowcost=(int *) malloc(N*sizeof(int));
	int *visit=(int *) malloc(N*sizeof(int));
	
	for(i=0;i<N;i++)
	{
		lowcost[i]=farm[0][i];
		visit[i]=0;
	}
	visit[0]=1;
	
	while(count<=N-1)
	{
		min_lowcost=100001;
		min_node=0;
		for(i=1;i<N;i++)
		{
			if(lowcost[i]<min_lowcost&&visit[i]==0)
			{
				min_lowcost=lowcost[i];
				min_node=i;
			}
		}
		visit[min_node]=1;
		sum+=lowcost[min_node];
		
		for(i=1;i<N;i++)
		{
			if(farm[min_node][i]!=0&&farm[min_node][i]<lowcost[i]&&visit[i]==0)
				lowcost[i]=farm[min_node][i];
		}
		count++;	
	}
    printf("%d\n",sum);
	free(lowcost);
	free(visit);
}

int main()
{
	int N;
	while(~scanf("%d",&N))
	{
        init(N);		
		prim(N);       		
	}
	return 0;
}

2.2 POJ 1789


思路:先得到每两个truck type之间的距离,建立完全图,计算最小生成树的路径之和。

源代码:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define MAX 2000
#define inf 0xffff

char truck_type[MAX][7];
int dis_graph[MAX][MAX]={inf};

int get_dis(char a[],char b[])
{
	int i,distance=0;
	for(i=0;i<7;i++)
	{
		if(a[i]!=b[i])
			distance++;
	}
	return distance;
}

void prim(int n)
{
	int i,count=1,Q=0,min_node=0,min_lowcost;
	int *lowcost=(int *)malloc(n*sizeof(int));
    int *visit=(int *) malloc(n*sizeof(int));
	
	for(i=0;i<n;i++)
		lowcost[i]=dis_graph[0][i];
    memset(visit,0,n*sizeof(int));
	visit[0]=1;
	
	while(count<=n-1)
	{
		min_lowcost=8;
		for(i=1;i<n;i++)
		{
			if(lowcost[i]<min_lowcost&&visit[i]==0)
			{
				min_lowcost=lowcost[i];
				min_node=i;
			}
		}
		
		visit[min_node]=1;
        Q+=lowcost[min_node];

		for(i=1;i<n;i++)
		{
			if(dis_graph[min_node][i]<lowcost[i]&&visit[i]==0)
				lowcost[i]=dis_graph[min_node][i];
		}
		count++;
	}
	free(lowcost);
	free(visit);

	printf("The highest possible quality is 1/%d.\n",Q);
}

int main()
{
	int i,j,n;
	while(scanf("%d",&n)&&n)
	{
		for(i=0;i<n;i++)
			scanf("%s",truck_type[i]);
		for(i=0;i<n;i++)
			for(j=i+1;j<n;j++)
				dis_graph[i][j]=dis_graph[j][i]=get_dis(truck_type[i],truck_type[j]);
			
		prim(n);
	}
	return 0;
}

2.3 POJ 2421


思路:将已建立的路的权值标记为0。

源代码:

2421Accepted204K0MSC1075B2013-03-01 20:43:58

#include "stdio.h"
#include "stdlib.h"
#define MAX 100

int road[MAX][MAX]={0};

void init(int N)
{
	int a,b,i,j,Q;
	for(i=0;i<N;i++) 
		for(j=0;j<N;j++)
			scanf("%d",&road[i][j]);
		
	scanf("%d",&Q);
	for(i=0;i<Q;i++)
	{
		scanf("%d%d",&a,&b);
		road[a-1][b-1]=road[b-1][a-1]=0;
	}
}

void prim(int N)
{
	int i,count=1,sum=0,min_node,min_lowcost;
	int *lowcost=(int *) malloc(N*sizeof(int));
	int *visit=(int *) malloc(N*sizeof(int));

	for(i=0;i<N;i++)
	{
		lowcost[i]=road[0][i];
		visit[i]=0;
	}
	visit[0]=1;

	while(count<=N-1)
	{
		min_lowcost=1001;
		min_node=0;
		for(i=1;i<N;i++)
			if(lowcost[i]<min_lowcost&&visit[i]==0)
			{
				min_lowcost=lowcost[i];
				min_node=i;
			}
		visit[min_node]=1;
		sum+=lowcost[min_node];

		for(i=1;i<N;i++)
			if(road[min_node][i]<lowcost[i]&&visit[i]==0)
				lowcost[i]=road[min_node][i];
		count++;	
	}
    printf("%d",sum);
	free(lowcost);
	free(visit);
}

int main()
{
	int N;
	while(~scanf("%d",&N))
	{
        init(N);		
		prim(N);       		
	}
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值