[USACO06NOV]路障---严格次短路

Description

贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。 贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。

Solution

今天考试的第三题, 出个这么水的原题是什么意思?
不巧的是一个多月前我刚做过, 更不巧的是今天做错了.

Code

这是我之前的代码, 那时候我还是个用指针建图的少年.

#include <queue>
#include <stdio.h>
#include <string.h>
#include <algorithm>
const int N = 40005;
const int inf = 0x3f3f3f3f;
using std:: queue;
using std:: pair;
using std:: make_pair;
#define Read(___) scanf("%d", &___)

struct Edge {
    int v, c; Edge *nxt;
    Edge() : nxt(NULL), v(0), c(inf) {}
    Edge(int _, int __) : nxt(NULL), v(_), c(__) {}
};


class Graph {
    int n, m, vis[N];
    Edge *head[N];
public:
    Graph(int _) { n = _; for (int i = 0; i <= n; i += 1) head[i] = new Edge(); }
    void AddEdge(int u, int v, int c) {
        Edge *tmp = head[u], *t = new Edge(v, c); t->nxt = tmp, head[u] = t;
    }
    void InitGraph(int m, bool isdirect, int val) {
        int u, v, c = val;
        for (int i = 0; i < m; i += 1) {
            scanf("%d%d", &u, &v); if (!val) scanf("%d", &c);
            AddEdge(u, v, c); if (isdirect) AddEdge(v, u, c);
        }
    }
    void MinDistance(int s, int *dis) {
        memset(dis, 0x3f, 4 * n + 4);
        memset(vis, false, 4 * n + 4);
        queue<int> que;
        que.push(s), vis[s] = true, dis[s] = 0;
        for (int top; !que.empty(); que.pop()) {
            top = que.front(); vis[top] = false;
            for (Edge *t = head[top]; t; t = t->nxt) {
                if (dis[t->v] > dis[top] + t->c) {
                    dis[t->v] = dis[top] + t->c;
                    if (!vis[t->v]) vis[t->v] = true, que.push(t->v);
                }
            }
        }
    }
#define P pair<int,int> 
    void SecondaryShortCircuit(int s, int *dis, int *sdis) {
        memset(dis, 0x3f, 4 * n + 4);
        memset(sdis, 0x3f, 4 * n + 4);
        std:: priority_queue<P, std:: vector<P> , std:: greater<P> >que;
        dis[s] = 0, que.push(make_pair(0, 1));
        for (P top; !que.empty(); que.pop()) {
            top = que.top(); int t = top.second, d = top.first; 
            if (sdis[t] < top.first) continue;
            for (Edge *i = head[t]; i; i = i->nxt) {
                int D = d + i->c;
                if (dis[i->v] > D) {
                    std:: swap(dis[i->v], D);
                    que.push(make_pair(dis[i->v], i->v));
                }
                if (sdis[i->v] > D and dis[i->v] < D) {
                    sdis[i->v] = D;
                    que.push(make_pair(sdis[i->v], i->v));
                }
            }
        }
    }
};

int d1[N], d2[N], d3[N];
int main () {
    int n, m; scanf("%d%d", &n, &m);
    Graph *G = new Graph(n); G->InitGraph(m, 1, 0);
    G->SecondaryShortCircuit(1, d1, d2);
    printf("%d", d2[n]);
    return 0;
}
原文地址:https://www.cnblogs.com/qdscwyy/p/9804043.html