题目链接: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和SPFA都可以。
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;
}

Spfa: 

#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;
}