HDU 3790 最短路径问题

Description

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

Input

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。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
//这个跟最短路径是一样的做法,只不过是加多花费的更新而已。
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxDis 999999999
#define maxN  1005
using namespace std;
int road[maxN][maxN][2];
int dis[maxN];  //保存一个点到另一个点的路径长度。
int cost[maxN]; //保存一个点到某一个点的花费。
bool visit[maxN];
void minLength(int s,int t,int n)
{
    for(int i = 1 ; i <= n; i++)
    {
        visit[i] = false;
        dis[i] = road[s][i][0];
        cost[i] = road[s][i][1];
    }
    dis[s] = 0;
    cost[s] = 0;
    visit[s] = true;
    for(int i = 1 ; i <= n; i++)
    {
        int min = maxDis;
        int index = 0;
        for(int j = 1 ; j <= n; j++)
        {
            if(!visit[j] && dis[j] < min)
            {
                min = dis[j];
                index = j;
            }
        }
        visit[index] = true;
        for(int j = 1 ; j <= n; j++)
        {
            if(!visit[j] && road[index][j][0] < maxDis && dis[index] + road[index][j][0] < dis[j])
            {
                dis[j] = dis[index] + road[index][j][0];
                cost[j] = cost[index] + road[index][j][1];
            }
            else if(!visit[j] && dis[index] + road[index][j][0] == dis[j])//当路径长度相同的时候,加多花费的更新
            {
                if(cost[j] > cost[index] + road[index][j][1])
                {
                    cost[j] = cost[index] + road[index][j][1];
                }
            }
        }
    }
   cout<<dis[t]<<" "<<cost[t]<<endl;
}
int main()
{
	int n,m;
	while(cin>>n>>m && n && m)
	{
		for(int i = 1 ; i <= n; i++)
		{
			for(int j = 1 ; j <= n; j++)
			{
			    if(i == j)
			    {
			        road[i][j][0] = 0;
			        road[i][j][1] = 0;
			    }
			    else
			    {
			         road[i][j][1] = maxDis;
			         road[i][j][0] = maxDis;
			    }

			}
		}
		int a,b,x,p;
		for(int i = 0 ; i < m ;i++)
		{
			//cin>>a>>b>>x>>p;
			scanf("%d%d%d%d",&a,&b,&x,&p);//用cin会超时,所以用scanf读入数据。。。
			if (road[a][b][0] > x)
			{
			    road[a][b][0] = x;
			    road[b][a][0] = x;
			    road[a][b][1] = p;
			    road[b][a][1] = p;
			}
		}
		int s,t;
		cin>>s>>t;
		    if(s > t)
		    {
		        minLength(s,t,n);
		    }
		    else
		    {
		        minLength(t,s,n);
		    }
	}
	return 0;
}

 

原文地址:https://www.cnblogs.com/T8023Y/p/3243126.html