7-9 旅游规划 (25分)(最短路bellman-ford,dijskra)

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。

输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

输入样例:

4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20  

输出样例:

3 40

bellman-ford

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
int inf=0x3f3f3f3f;
int n,m,s,d,a[1000005][5],m1=inf,m2=inf;
int main()
{	
	int i,j,s,c,t,x,y,z,d1[505],d2[505];	
	scanf("%d %d %d %d",&n,&m,&s,&d);
	for(i=1;i<=m;i++){
		scanf("%d %d %d %d",&a[i][1],&a[i][2],&a[i][3],&a[i][4]);
		a[i+m][1]=a[i][2];//
		a[i+m][2]=a[i][1];//
		a[i+m][3]=a[i][3];//由于是无向图,要加上这个 
		a[i+m][4]=a[i][4];//
	}
	memset(d1,inf,sizeof(d1));
	memset(d2,inf,sizeof(d2));
	d1[s]=d2[s]=0; 
	for(j=1;j<n;j++){//因为除起点外有n-1个点,所以n-1次循环起点足够到达每一个点 
		int flag=0;
		for(i=1;i<=m*2;i++){ 
			if(d1[a[i][2]]>d1[a[i][1]]+a[i][3]){
				d1[a[i][2]]=d1[a[i][1]]+a[i][3];
				d2[a[i][2]]=d2[a[i][1]]+a[i][4];
				flag=1;
			}
			else if(d1[a[i][2]]==d1[a[i][1]]+a[i][3]&&d2[a[i][2]]>d2[a[i][1]]+a[i][4]){
			//	d1[a[i][2]]=d1[a[i][1]]+a1[i][3];
				d2[a[i][2]]=d2[a[i][1]]+a[i][4];
				flag=1;
			}
		}
		if(!flag) break;
	}
	printf("%d %d",d1[d],d2[d]);
	return 0;
}

dijskra (c)

迪杰斯特拉算法过程:
1.数组d中存放源点到其他点的最短距离,每次从数组d中选一个值最小且没有被访问过的点;
2.如果经过此点到其他点距离更短,则更新数组d;
3.标记此点已访问过,遍历其他点,直到所有点被访问完。

#include<stdio.h>
#define maxn 1005
int main()
{
	int i,j,n,m,x,y,l,c,v,s,d,a[505][505][3],f[maxn]={0},b[maxn],p[maxn];
	scanf("%d %d %d %d",&n,&m,&s,&d);
	for(i=0;i<n;i++)
		for(j=0;j<n;j++){
		//	a[i][j][0]=a[j][i][0]=maxn;	a[i][j][1]=a[j][i][1]=maxn;
			a[i][j][0]=maxn;a[i][j][1]=maxn;
		}
			
	while(m--){
		scanf("%d %d %d %d",&x,&y,&l,&c);
		a[x][y][0]=a[y][x][0]=l;
		a[x][y][1]=a[y][x][1]=c;
	}
	
	for(i=0;i<n;i++){
		b[i]=a[s][i][0];
		p[i]=a[s][i][1];
	}	
//	f[s]=1;
	b[s]=0;
	p[s]=0;
	b[n]=maxn;
	while(1){
		v=n;
		for(i=0;i<n;i++){
			if(!f[i]&&b[i]<b[v])
				v=i;
		}
		if(v==n) break;
		f[v]=1;
		for(i=0;i<n;i++){
			if(!f[i]&&a[v][i][0]<maxn){
				if(b[v]+a[v][i][0]<b[i]){
					b[i]=b[v]+a[v][i][0];
					p[i]=p[v]+a[v][i][1];
				}					
				else if( b[v]+a[v][i][0]==b[i]&&p[v]+a[v][i][1]<p[i]){
			//		b[i]=b[v]+a[v][i][0];
					p[i]=p[v]+a[v][i][1];
				}								
			}
		}
	}
	printf("%d %d",b[d],p[d]);

	return 0; 
} 

dijskra (c++)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int N=505;
const int inf=0x3f3f3f3f;
typedef long long ll;
int n,m,st,ed;
int a[N][N][2];
int vis[N],d1[N],d2[N];
void spfa(){
	memset(d1,inf,sizeof(d1));
	memset(d2,inf,sizeof(d2));
	d1[st]=d2[st]=0;
	priority_queue<pair<int,int> >q;
	q.push(make_pair(0,st));
	while(!q.empty()){
		int t=q.top().second;
		q.pop();
		if(vis[t]) continue;
		vis[t]=1;
		for(int i=1;i<=n;i++){
			if(a[t][i][0]!=0){
				if(d1[i]>d1[t]+a[t][i][0]){
					d1[i]=d1[t]+a[t][i][0];
					d2[i]=d2[t]+a[t][i][1];
					if(!vis[i]) 
						q.push(make_pair(-d1[i],i));
				}
				else if(d1[i]==d1[t]+a[t][i][0]&&d2[i]>d2[t]+a[t][i][1]){
					d2[i]=d2[t]+a[t][i][1];
					if(!vis[i]) 
						q.push(make_pair(-d1[i],i));
				}
			}
		}
	}
}
int main()
{
	int i,j,k,x,y,len,value;
	scanf("%d %d %d %d",&n,&m,&st,&ed);
	for(i=0;i<m;i++){
		scanf("%d %d %d %d",&x,&y,&len,&value);
		a[x][y][0]=a[y][x][0]=len;
		a[x][y][1]=a[y][x][1]=value;
	}
	spfa();
	printf("%d %d",d1[ed],d2[ed]);
	return 0;
}

卑微dfs

最后一个点超时

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
int inf=0x3f3f3f3f;
int n,m,s,d,a[505][505],b[505][505],m1=inf,m2=inf;
int v[505];
void dfs(int start,int sum1,int sum2){
	if(start==d){
		if(sum1<m1){
			m1=sum1;
			m2=sum2;
		}
		else if(sum1==m1&&sum2<m2){
			m1=sum1;
			m2=sum2;
		}
		return;
	}
	v[start]=1;
	for(int i=0;i<n;i++){
		if(!v[i]&&a[start][i]&&sum1+a[start][i]<=m1){
			dfs(i,sum1+a[start][i],sum2+b[start][i]);
		}
	}
	v[start]=0;
}
int main()
{	
	int i,j,s,c,t,x,y,z;	
	scanf("%d %d %d %d",&n,&m,&s,&d);
	while(m--){
		scanf("%d %d %d %d",&x,&y,&z,&t);
		a[x][y]=a[y][x]=z;
		b[x][y]=b[y][x]=t;
	}
	dfs(s,0,0);
	printf("%d %d",m1,m2);
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值