HDU 3790 最短路徑問題 (雙重權值)

來源:互聯網
上載者:User
最短路徑問題

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

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 2
1 2 5 6
2 3 4 5
1 3
0 0
 
 
Sample Output
9 11
 
 
 
剛做的時候看錯題目,以為分別求最短路徑和最少費用。。(兩條路),然後以為2次dijkstra就OK
 
其實題目要求的只是最短路徑,而那個費用是再這條路徑上的最少費用。
 
這裡要注意的是:兩個點中可以有重邊,特別是最短的路徑的重邊,應為我們求的時候只求第一個最小的的路徑(以後在

遇到相同的最小路徑的時候就不會換值),而這條路徑不能保證費用最小。
 
所以當路徑最小時,還要判斷費用是不是最小,從而換值。
還有個就是printf()的從右向左執行的問題。如果後面不加個ans,直接在printf() 裡用dijkstra()的話後面那個d

[end].p就會是無窮大。

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cctype>
#include <cstring>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <algorithm>
 
using namespace std;
//Constant Declaration
/*--------------------------*/
//#define LL long long 
#define LL __int64
const int M=1100;//最多點數
const int INF=1<<30;
const double EPS = 1e-11;
const double PI = acos(-1.0);
/*--------------------------*/
// some essential funtion
/*----------------------------------*/
void Swap(int &a,int &b){   int t=a;a=b;b=t; }
int Max(int a,int b){   return a>b?a:b;  }
int Min(int a,int b){   return a<b?a:b;  }
int Gcd(int a,int b){   while(b){b ^= a ^=b ^= a %= b;}  return a; }
/*----------------------------------*/
//for (i = 0; i < n; i++)
/*----------------------------------*/

struct djs
{
    int l,p;
}d[M],g[M][M];

bool used[M];//標記i是否被用過
void init(int n)
{
    int i, j;
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            g[i][j].l = INF;//初始化圖沒有邊,預設為INF,為了一定更新
            g[i][j].p = INF;
        }
    }
    for (i = 1; i <= n; i++)
    {
        d[i].l = INF;
        d[i].p = INF;
    }
    
    memset(used, 0, sizeof(used));
}

int dijkstra(int star, int end, int n)//起點,終點,總點數(編號為1,2...n)
{
    int min_num;//最小值的位置
    int i;
    d[star].l= 0;
    d[star].p= 0;//起點到起點的最短距離為0,很重要的一步
    for (int cnt = 0; cnt < n; cnt++)//注意別用while(n--),這樣會改變n的值。n次貪心
    {
        int min = INF;
        for (i = 1; i <= n; i++)
        {
            if (!used[i] && d[i].l < min)
            {
                min = d[i].l;
                min_num = i;
            }
        }
        
        used[min_num] = 1;

        //把d[min_num]作為中間點,對相鄰的點做鬆弛
        for (i = 1; i <= n; i++)
        {
            if (!used[i] && d[i].l > d[min_num].l + g[min_num][i].l)
            {
                d[i].l = d[min_num].l + g[min_num][i].l;
                d[i].p = d[min_num].p + g[min_num][i].p;
            }
            if (!used[i] && d[i].l == d[min_num].l + g[min_num][i].l && d[i].p > d[min_num].p + g[min_num]

[i].p)//這裡的判斷是關鍵
            {
                d[i].p = d[min_num].p + g[min_num][i].p;
            }
        }
        
    }
    return d[end].l;
}

int main()
{
 //freopen("in.txt","r",stdin);
 //freopen("out.txt","w",stdout);
 //int t, case1 = 0;
 //scanf("%d", &t);
 int n, m;
 int i, j;
 while (scanf("%d%d", &n, &m), n + m)
 {
     init(n);
    for (i = 0; i < m; i++)
    {
        int a, b, c, c1;
        scanf("%d%d%d%d", &a, &b, &c, &c1);
        if (g[a][b].l > c)
        {
            g[b][a].l = g[a][b].l = c;
            g[b][a].p= g[a][b].p = c1;
        }//此題為無向圖
        if (g[a][b].l == c && g[b][a].p > c1)//這裡的判斷是關鍵
        {
            g[b][a].p= g[a][b].p = c1;
        }

    }
    int star, end,ans;
    scanf("%d%d", &star, &end);
    ans = dijkstra(star, end, n);
    printf("%d %d\n", ans, d[end].p);
 }
 
 return 0;
}
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.