Constructing Roads(prim算法)

这篇博客介绍了一个利用Prim算法解决最小生成树问题的实例。内容包括输入村庄数量、已有道路距离矩阵以及已建成道路的信息,通过Prim算法找到连接所有村庄的最短路径总长度。代码中展示了Prim算法的实现,适用于稠密图,适用于解决此类图论问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Constructing Roads

‎有N个村庄,编号从1到N,你应该建立一些道路,使每两个村庄可以相互连接。我们说,如果只有A和B之间有一条路,或者C村之间有一条C村,A和C之间有一条路,C和B之间有一条连接的道路,那么A和B两个村庄是相连的。‎
‎我们知道,一些村庄之间已经有一些道路,你的工作是建造一些道路,使所有的村庄都连接起来,所有道路的长度是‎
‎最小的。‎

‎输入‎

‎第一行是整数N(3 +lt;=100),即村庄的数量。然后是 N 线,其中 i-th 包含 N 整数,而这些 N 整数的 j-th 是村庄 i 和村庄 j‎

‎之间的距离(距离应该是 [1,1000]内的整数),然后有一个整数 Q (0 +lt;= N * (N + 1) / 2)。然后是 Q 线,每行包含两个整数 a 和 b (1 +lt; a < b <] N), 这意味着 A 村和村庄 b 之间的道路已经建成。‎

‎输出‎

‎您应该输出一条包含整数的线路,该整数是要修建的所有道路的长度,以便连接所有村庄,并且此值是最低值。‎

Sample Input

3
0 990 692
990 0 179
692 179 0
1
1 2

Sample Output

179

Sponsor

实现代码:

 

#include<stdio.h>
#include<string.h>
#include<algorithm>

using namespace std;

int inf=0x3f3f3f;
int map[105][105],dis[105],book[105];
int m,n;

int prim()
{
	int i,j,k,sum=0,u,min;
	
	for(i=1;i<=n;i++)//循环范围根据题目从1开始 ,这里初始化一下 
	{
		dis[i]=map[1][i];//表示原点到其他点的距离 
		book[i]=0;
	}
	book[1]=1;
	//dis[1]=0;
	
	for(i=1;i<n;i++)
	{
		min=inf;
		for(j=1;j<=n;j++)
		{
			if(book[j]==0&&min>dis[j])
			{
				min=dis[j];
				u=j;
			}
		}
		book[u]=1;
		sum+=dis[u];
		
		for(j=1;j<=n;j++)
		{
			if(book[j]==0&&dis[j]>map[u][j])
			dis[j]=map[u][j];
		}
	}
	return sum;
}

int main()
{
	int a,b,c,i,j,k;
	
	while(scanf("%d",&n)!=EOF)
	{
		memset(map,inf,sizeof(map));//初始化一下 
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				scanf("%d",&map[i][j]);
			}
		}
		scanf("%d",&a);
		for(i=1;i<=a;i++)
		{
			scanf("%d%d",&b,&c);
			map[b][c]=map[c][b]=0;
		}
		
		printf("%d\n",prim());
	}
	return 0;
}

 

附加:

1.prim算法适用于稠密图O(N^2),kruskal适合稀疏图O(eloge).

2.Output Limit Exceeded
程序在时间限制内没运行结束,就会出Output Limit Exceeded错误
程序返回的结果是一直输出某个结果,死循环输出的那种
解决:多半是while的输入那没有加!=EOF

懵懵的可以先看这个:https://blog.csdn.net/with_wine/article/details/113972924打好基础 

想提高的点这里:https://blog.csdn.net/with_wine/article/details/113980197

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值