HDU 3790.最短路径问题【最短路径Dijkstra算法】【4月14】

来源:互联网 发布:云计算国内外研究现状 编辑:程序博客网 时间:2024/05/16 03:46

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20635    Accepted Submission(s): 6118


Problem 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 21 2 5 62 3 4 51 30 0
 

Sample Output
9 11
 
题目的裸地Dijkstra算法,但是需要在输入的时候保存最优的。如果两点之间多条边,保存最短边;两边同长,保存价值小的边。再做Dijkstra算法时也要保存价值。代码如下:

#include<iostream>#include<cstdio>#include<vector>#include<cstring>using namespace std;const int MAXN = 1005;int dist[MAXN], c[MAXN], cost[MAXN][MAXN], len[MAXN][MAXN], vt[MAXN];int n, m, s, t, a, b, d, p;void Dijkstra(int root, int finish){    memset(vt, 0, sizeof(vt));    for(int i = 1;i <= n; ++i)    {        c[i] = 0x7FFFFFFF;        dist[i] = 0x7FFFFFFF;    }    dist[root] = c[root] = 0;    vt[root] = 1;    for(int i = 1;i <= n; ++i)    {        int minx = 0x7FFFFFFF;        for(int j = 1;j <= n; ++j)        {            if(vt[j] == 1) continue;            if(len[root][j] == 0x7FFFFFFF) continue;            if(dist[j] > dist[root] + len[root][j])            {                dist[j] = dist[root] + len[root][j];                c[j] = c[root] + cost[root][j];            }            else if(dist[j] == dist[root] + len[root][j])//路径同长,要价值小的            {                if(c[j] > c[root] + cost[root][j])                {                    c[j] = c[root] + cost[root][j];                }            }        }        for(int j = 1;j <=  n; ++j)        {            if(vt[j] == 0 && dist[j] < minx)            {                root = j;                minx = dist[j];            }        }        vt[root] = 1;    }    cout << dist[finish] <<" "<< c[finish] << endl;}int main(){    while(scanf("%d %d", &n, &m) == 2 && n && m)    {        for(int i = 1;i <= n; ++i)        for(int j = 1;j <= n; ++j)            len[i][j] = 0x7FFFFFFF;        for(int i = 1;i <= m; ++i)        {            scanf("%d %d %d %d", &a, &b, &d, &p);            if(d < len[a][b])//两点之间多条边,保留短的            {                len[a][b] = len[b][a] = d;                cost[a][b] = cost[b][a] = p;            }            else if(d == len[a][b])//边同长,保留价值小的            {                if(p < cost[a][b]) cost[a][b] = cost[b][a] = p;            }        }        scanf("%d %d", &s, &t);        Dijkstra(s, t);    }    return 0;}



0 0