HDOJ 3790 最短路徑問題

最短路徑問題
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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

輸出 一行有兩個數, 最短距離及其花費。

題意很明顯,求兩個點之間的最短路徑,使用單源最短路的DIJ,數據範圍還是蠻大的用vector和優先隊列來做,先來理一下思路,求兩個點的最短路徑,如果最短路徑有多條則輸出花費最小的,可以看出,判斷的時候會加入花費問題,當路徑相等時判斷花費,先用vector存點和邊,把起點壓入隊列,然後不斷的把最小的符合題意的點和邊彈出去鬆弛剩下的點,鬆弛成功入隊,直到隊列爲空。


#include<algorithm>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
struct node
{
    int now;
    int len;
    int val;
    bool operator <(const node &x)const   //優先隊列的重載小於符號
    {
        if(len>x.len)
            return true;
        else if(len<x.len)
            return false;
        else if(len==x.len)
        {
            if(val>x.val)
                return true;
            else
                return false;
        }
    }
};
struct node2   //vector
{
    int next;
    int len;
    int val;
};
priority_queue<node> que;
int main()
{
    int n,m;
    int dis[1005];
    int use[1005];
    int v[1005];
    int l,r;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;
        while(!que.empty())    //清空隊列
            que.pop();
        for(int i=1;i<=n;i++)
            v[i]=dis[i]=INF;
        memset(use,0,sizeof(use));
        vector<node2>a[1005];
        int x,y,z,b;
        node2 t;
        while(m--)
        {
            scanf("%d%d%d%d",&x,&y,&z,&b);
            t.next=y;
            t.len=z;
            t.val=b;
            a[x].push_back(t);

            t.next=x;
            t.len=z;
            t.val=b;
            a[y].push_back(t);
        }
        scanf("%d%d",&l,&r);
        dis[l]=0;                               //加入起點
        v[l]=0;
        node temp,next;
        temp.len=0;
        temp.now=l;
        que.push(temp);

        while(!que.empty())
        {
            temp=que.top();
            que.pop();
            if(use[temp.now]==1)
                continue;
            use[temp.now]=1;
            for(int i=0;i<a[temp.now].size();i++)
            {
                int now=temp.now;
                int templen=dis[now]+a[now][i].len;
                int tempval=v[now]+a[now][i].val;
                if(dis[a[now][i].next]>templen)
                {
                    dis[a[now][i].next]=templen;    //更新
                    v[a[now][i].next]=tempval;
                    next.now=a[now][i].next;
                    next.len=templen;
                    next.val=tempval;
                    que.push(next);        //入隊
                }
                else if(dis[a[now][i].next]==templen)
                {
                    if(v[a[now][i].next]>tempval)
                    {
                        dis[a[now][i].next]=templen;
                        v[a[now][i].next]=tempval;
                        next.now=a[now][i].next;
                        next.len=templen;
                        next.val=tempval;
                        que.push(next);
                    }
                }
            }
        }
        printf("%d %d\n",dis[r],v[r]);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章