scau 最小生成树和最短路问题

文章提供了两道编程题,分别涉及最小生成树(Prim算法)和最短路径(Dijkstra算法)问题。在最小生成树问题中,给定一个带权无向图,要求求解最小生成树的边权和;最短路问题则要求从起点到终点的最低费用。代码示例使用了C++编写,通过构建邻接矩阵和更新距离数组来解决问题。
摘要由CSDN通过智能技术生成

18448 最小生成树

时间限制:1000MS  代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题   语言: G++;GCC;VC

Description

给定结点数为n,边数为m的带权无向连通图G,所有结点编号为1,2,3....n。
求图G的最小生成树的边权和。



 

输入格式

第一行两个正整数n和m。n,m<=2000
之后的m行,每行三个正整数a,b,w,描述一条连接结点a和b,边权为w的边。1=<a,b<=n,w<=10^18。
注意可能存在重边和自环。


 

输出格式

一个整数表示图G的最小生成树的边权和(注意用长整型)。


 

输入样例

7 12
1 2 9
1 5 2
1 6 3
2 3 5
2 6 7
3 4 6
3 7 3
4 5 6
4 7 2
5 6 3
5 7 6
6 7 1


 

输出样例

16
#include<iostream>
#include<algorithm>

using namespace std;

typedef long long ll;
const int N=2023,INF=1e18;
ll n,m,a,b,w;
ll e[N][N],d[N],v[N];

ll prim(){
	d[1]=0;
	ll sum=0;
	for(int i=1;i<=n;++i){
		int cur=-1;
		for(int j=1;j<=n;++j){
			if(!v[j]&&(cur==-1||d[j]<d[cur])){
				cur=j;
			}
		}
		
		if(d[cur]>=INF){
			return INF;
		}
		sum+=d[cur];
		v[cur]=1;
		for(int k=1;k<=n;++k){
			if(!v[k])
				d[k]=min(d[k],e[cur][k]);
		}
	}
	return sum;
}

int main() {
	
	cin>>n>>m;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			e[i][j]=INF;
		}
	}
	for(int i=1;i<=n;++i){
		d[i]=INF;
	}
	for(int i=1;i<=m;++i){
		cin>>a>>b>>w;
		e[a][b]=min(e[a][b],w);
		e[b][a]=min(e[b][a],w);
	}
	cout<<prim();
	return 0;
}

 

18732 最短路问题

时间限制:1000MS  代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题   语言: G++;GCC

Description

现在有n个车站和m条直达公交线路,每条线路都有一个固定票价。
作为一个窮人,你打算从车站1坐车到车站n,请计算下车站1到车站n的最少花费。
如果车站1无法到达车站n,请输出-1。
注意,在车站x和y之间可能存在不止一条线路。



 

输入格式

第一行两个整数n和m,表示车站数量和线路数量。(1<=n<=100),(1<=m<=1000)
第二行至第m+1行,每行3个整数a,b,x,代表车站a和车站b之间有一条票价为x的公交线路,公交线路是双向的。


 

输出格式

输出车站1到n的最小花费。


 

输入样例

4 4
1 2 4
2 3 7
2 4 1
3 4 6


 

输出样例

5
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=300,INF=0x3f3f3f3f;
int e[N][N],d[N],v[N];
int n,m,a,b,x;

int dijkstra(){
	d[1]=0;
	for(int i=1;i<=n;++i){
		int cur=-1;
		for(int j=1;j<=n;++j){
			if(!v[j]&&(cur==-1||d[j]<d[cur])){
				cur=j;
			}
		}
		v[cur]=1;
		for(int k=1;k<=n;++k){
			if(!v[k]){
				d[k]=min(d[k],d[cur]+e[cur][k]);
			}
		}	
	}
	return d[n]>=INF?-1:d[n];
}
int main() {
	
	cin>>n>>m;
	memset(d,0x3f,sizeof(d));
	memset(e,0x3f,sizeof(e));
	for(int i=1;i<=m;++i){
		cin>>a>>b>>x;
		e[a][b]=min(e[a][b],x);
		e[b][a]=min(e[b][a],x);
	}
	cout<<dijkstra();
	return 0;
}












 

分析:

最小生成树跟最短路代码非常像,只有很小的差别。

最小生成树解决的是用哪n-1条边可以将n个顶点连接组成,使得图的权重之和最小,因此d数组记录的是每个顶点到最小生成树之间的最短距离。

最短路解决的是从一个点出发到任意一点的最短距离,因此d数组记录的是从起点出发到该点的最短距离

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值