1. 程式人生 > >計蒜客 - 德克薩斯長角牛(最短路)

計蒜客 - 德克薩斯長角牛(最短路)

https://nanti.jisuanke.com/t/230

  • 1000ms
  • 65536K

題目描述

德克薩斯純樸的民眾們這個夏天正在遭受巨大的熱浪!!!他們的德克薩斯長角牛吃起來不錯,可是他們並不是很擅長生產富含奶油的乳製品。Farmer John此時以先天下之憂而憂,後天下之樂而樂的精神,身先士卒地承擔起向德克薩斯運送大量的營養冰涼的牛奶的重任,以減輕德克薩斯人忍受酷暑的痛苦。FJ已經研究過可以把牛奶從威斯康星運送到德克薩斯州的路線。這些路線包括起始點和終點先一共經過T(1 <= T <= 2,500)個城鎮,方便地標號為1到T。除了起點和終點外地每個城鎮由兩條雙向道路連向至少兩個其它地城鎮。每條道路有一個通過費用(包括油費,過路費等等)。考慮這個有7個城鎮的地圖。城鎮5是奶源,城鎮4是終點(括號內的數字是道路的通過費用)。

經過路線5-6-3-4總共需要花費3  (5-> 6)  +  4  (6-> 3)  +  3  (3-> 4)  =  10的費用。 給定一個地圖,包含C (1 <= C <= 6,200)條直接連線2個城鎮的道路。每條雙向道路由兩個端點Rs和Re (1 <= Rs <= T; 1 <= Re <= T),和花費(1 <= Ci <= 1,000)組成。求從起始城鎮Ts (1 <= Ts <= T)到終點城鎮Te(1 <= Te <= T)最小的總費用。

輸入格式

第一行: 4個由空格隔開的整數: T, C, Ts, Te
第2到第C+1行: 第i+1行描述第i條道路。有3個由空格隔開的整數: Rs,Re和Ci

輸出格式

一個單獨的整數表示Ts到Te的最短路的長度。
所有測試資料保證至少存在一條道路。5->6->1->4 (3 + 1 + 3 = 7)

樣例輸入

7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

樣例輸出

7

解題思路

這一題就是一道單源最短路問題,Dijkstra和Bellman-Ford都可以。
Dijkstra:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef pair <int, int> PII;
struct edge {
    int u, v, w;
}e[12550];
int cnt, f[2550], vis[2550], dis[2550];
void Add(int u, int v, int w)
{
    e[++cnt] = (edge){f[u], v, w};
    f[u] = cnt;
}
int main()
{
    int t, c, u, v, w, ts, te;
    while (~scanf("%d%d%d%d", &t, &c, &ts, &te))
    {
        cnt = 0;
        priority_queue <PII, vector<PII>, greater<PII> > Q;
        memset(f, 0, sizeof(f));
        memset(vis, 0, sizeof(vis));
        memset(dis, 0x3f, sizeof(dis));
        for (int i = 0; i < c; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            Add(u, v, w);
            Add(v, u, w);
        }
        dis[ts] = 0;
        Q.push(PII(0, ts));
        while (!Q.empty())
        {
            PII x = Q.top();
            Q.pop();
            if (vis[x.second])
                continue;
            vis[x.second] = 1;
            for (int i = f[x.second]; i; i = e[i].u)
            {
                v = e[i].v;
                if (dis[v] > x.first + e[i].w)
                {
                    dis[v] = x.first + e[i].w;
                    Q.push(PII(dis[v], v));
                }
            }
        }
        printf("%d\n", dis[te]);
    }
    return 0;
}

Bellman-Ford: 

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct edge {
    int u, v, w;
}e[12550];
int cnt, f[2550], vis[2550], dis[2550];
void Add(int u, int v, int w)
{
    e[++cnt] = (edge){f[u], v, w};
    f[u] = cnt;
}
int main()
{
    int t, c, u, v, w, ts, te;
    while (~scanf("%d%d%d%d", &t, &c, &ts, &te))
    {
        cnt = 0;
        queue <int> Q;
        memset(f, 0, sizeof(f));
        memset(vis, 0, sizeof(vis));
        memset(dis, 0x3f, sizeof(dis));
        for (int i = 0; i < c; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            Add(u, v, w);
            Add(v, u, w);
        }
        dis[ts] = 0;
        vis[ts] = 1;
        Q.push(ts);
        while (!Q.empty())
        {
            u = Q.front();
            Q.pop();
            vis[u] = 0;
            for (int i = f[u]; i; i = e[i].u)
            {
                v = e[i].v;
                if (dis[v] > dis[u] + e[i].w)
                {
                    dis[v] = dis[u] + e[i].w;
                    if (!vis[v])
                    {
                        vis[v] = 1;
                        Q.push(v);
                    }
                }
            }
        }
        printf("%d\n", dis[te]);
    }
    return 0;
}