最短路径问题 (图论入门+dijkstra(单源最短路))

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

Input

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。

最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。 

(1<n<=1000, 0<m<100000, s != t)

Output

输出 一行有两个数, 最短距离及其花费。

Sample Input

3 2
1 2 5 6
2 3 4 5
1 3
0 0

Sample Output

9 11

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;//很好用的无穷大 
const int N=1010;
int graph[N][N];// 各个边的距离 
int cost[N][N];// 各个边的花费 
int dis[N];   //  源点到各个点的距离 
int cost1[N]; // 源点到各个点的花费 
int in[N];    //标记是否 

int main(void)
{
	int n,m;
	while(~scanf("%d %d",&n,&m))
	{
		if(n==0&&m==0)
		break;
		int i,j;
		for(i=1;i<=n;i++)//初始化各个数组 
		{
			for(j=1;j<=n;j++)
			{
				if(i==j)
				{
					graph[i][j]=0;//到自身的距离为零 
					cost[i][j]=0;//
				}
				else
				{
					graph[i][j]=INF;
					cost[i][j]=INF;
				}
			}
			dis[i]=INF;
			cost1[i]=INF;
			in[i]=0;
		}
		
		while(m--)
		{
			int a,b,d,p;
			scanf("%d %d %d %d",&a,&b,&d,&p); 
			if(graph[a][b]>d)//如果有更小的距离的话就更新 
			{
				graph[a][b]=graph[b][a]=d;// 无向边 
				cost[a][b]=cost[b][a]=p;
			}
			else if(graph[a][b]==d&&cost[a][b]>p)//距离相等则更新花费更小的 
			{
				cost[a][b]=cost[b][a]=p;
			}
		}
		int a,b;
		scanf("%d %d",&a,&b);
		for(i=1;i<=n;i++)
		{
			dis[i]=graph[a][i];//起点到各个点的距离 
			cost1[i]=cost[a][i];//花费 
		}
		in[a]=1;//起点到起点距离已经确定不会改变 
		for(i=1;i<n;i++)
		{
			int mind=INF,mj;
			for(j=1;j<=n;j++)//寻找当前距离起点最近的点 
			{
				if(in[j]==0&&dis[j]<mind)
				{
					mind=dis[j];
					mj=j;//记住下标 
				}
			}
			in[mj]=1;//标记这个点到起点的距离已经确定(不可能再通过第三个点的中转使得到起点的距离变的更小,因为其他的点到起点的距离都是正数) 
			for(int k=1;k<=n;k++)
			{
				if(graph[mj][k]<INF)
				{
					if(graph[mj][k]+dis[mj]<dis[k])//利用mj点来松弛(或者说通过mj点的中转看能不能减少其他点到起点的距离)其他点到起点的距离 
					{
						dis[k]=graph[mj][k]+dis[mj];
						cost1[k]=cost[mj][k]+cost1[mj];
					}
					else if(graph[mj][k]+dis[mj]==dis[k])
					{
						cost1[k]=min(cost[mj][k]+cost1[mj],cost1[k]);
					}
				}
			}
		}
		printf("%d %d\n",dis[b],cost1[b]);//起点(a)到b点的距离,花费 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/nucleare/article/details/80342402