FOJ Problem 2261 浪里个浪

Posted ZefengYao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FOJ Problem 2261 浪里个浪相关的知识,希望对你有一定的参考价值。

                                                                                                                                                           Problem 2261 浪里个浪

Accept: 40    Submit: 106
Time Limit: 1500 mSec    Memory Limit : 32768 KB

技术分享 Problem Description

TonyY是一个喜欢到处浪的男人,他的梦想是带着兰兰姐姐浪遍天朝的各个角落,不过在此之前,他需要做好规划。

现在他的手上有一份天朝地图,上面有n个城市,m条交通路径,每条交通路径都是单行道。他已经预先规划好了一些点作为旅游的起点和终点,他想选择其中一个起点和一个终点,并找出从起点到终点的一条路线亲身体验浪的过程。但是他时间有限,所以想选择耗时最小的,你能告诉他最小的耗时是多少吗?

技术分享 Input

 

包含多组测试数据。

输入第一行包括两个整数n和m,表示有n个地点,m条可行路径。点的编号为1 - n。

接下来m行每行包括三个整数i, j, cost,表示从地点i到地点j需要耗时cost。

接下来一行第一个数为S,表示可能的起点数,之后S个数,表示可能的起点。

接下来一行第一个数为E,表示可能的终点数,之后E个数,表示可能的终点。

0<S, E≤n≤100000,0<m≤100000,0<cost≤100。

技术分享 Output

输出他需要的最短耗时。

技术分享 Sample Input

4 4 1 3 1 1 4 2 2 3 3 2 4 4 2 1 2 2 3 4

技术分享 Sample Output

思路:最短路裸模板题。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f

struct Edge {
    int from, to, dist;
    Edge(int u = 0, int v = 0, int w = 0) :from(u), to(v), dist(w) {}
};

struct HeapNode {
    int dist, u;  //顶点u距离s的距离为dist
    HeapNode(int w = 0, int x = 0) :dist(w), u(x) {}
    bool operator<(const HeapNode&rhs)const {
        return dist>rhs.dist;
    }
};

struct Graph {
    const static int V = 1e5 + 10+2;
    int n, m;
    vector<Edge>edges;    // 边集
    vector<int>G[V];
    bool done[V];   //是否已经永久标号
    int d[V];     //s到各个顶点的距离

    void init(int n) {
        this->n = n;
        for (int i = 0; i<n; i++)G[i].clear();
        edges.clear();
    }

    void addEdge(int from, int to, int dist) {
        edges.push_back(Edge(from, to, dist));
        m = edges.size();
        G[from].push_back(m - 1);
    }

    void dijkstra(const vector<int>&s) {
        memset(d, 0x3f, sizeof(d));
        memset(done, 0, sizeof(done));
        priority_queue<HeapNode>Q;
        int ns = s.size();
        for (int i = 0; i<ns; i++) {
            d[s[i]] = 0;
            Q.push(HeapNode(0, s[i]));
        }

        while (!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;  // 拿最小距离的顶点编号
            if (done[u])continue;  //每个顶点出发只可以松弛一次
            done[u] = true;
            for (int i = 0; i<G[u].size(); i++) {
                Edge&e = edges[G[u][i]];   //取出一条邻边
                if (d[e.to]>d[u] + e.dist) {
                    d[e.to] = d[u] + e.dist;
                    Q.push(HeapNode(d[e.to], e.to));
                }
            }
        }
    }

    int slove(const vector<int>&s, const vector<int>&t) {
        dijkstra(s);
        int res = inf, nt = t.size();
        for (int i = 0; i<nt; i++) {
            res = min(res, d[t[i]]);
        }
        return res;
    }

}slover;
vector<int>s, t;
int main() {
    //源点0,汇点n+1
    //freopen("in.txt","r",stdin);
    int n, m, u, v, w, S, E;
    while (scanf("%d %d", &n, &m) == 2) {
        slover.init(n + 2);
        s.clear(), t.clear();
        for (int i = 0; i<m; i++) {
            scanf("%d %d %d", &u, &v, &w);
            slover.addEdge(u, v, w);
        }
        s.push_back(0);
        scanf("%d", &S);
        for (int i = 0; i < S; i++) {
            int a;
            scanf("%d",&a);
            slover.addEdge(0,a,0);
        }
        scanf("%d", &E);
        t.resize(E);
        for (int i = 0; i < E; i++) {
            scanf("%d", &t[i]);
        }
        printf("%d\n", slover.slove(s, t));
    };
    return 0;
}

 



以上是关于FOJ Problem 2261 浪里个浪的主要内容,如果未能解决你的问题,请参考以下文章

[FZU2261]浪里个浪

FZU - 2261 浪里个浪 SPFA最短路

发现了两个神奇的网站!边做试验边学编程!

foj Problem 2282 Wand

FOJ Problem 2271 X

foj Problem 2275 Game