SGU145 Strange People

SGU145 Strange People

题目大意

给出一张无向图,找出S到T的第K短简单路径

算法思路

单源无环K短路,可以用偏离路径Yen算法解决
直接套用模板,算法的过程讲解可以在这里找到
顺便,SGU的数据有问题,提交总是返回PE

时间复杂度: O(KN3)

代码

/** * Copyright © 2015 Authors. All rights reserved. * * FileName: 145.cpp * Author: Beiyu Li <[email protected]> * Date: 2015-06-18 */
#include <bits/stdc++.h>

using namespace std;

#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)

typedef long long LL;
typedef pair<int, int> Pii;

const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;

const int maxn = 100 + 5;

class Yen {
        struct Path {
                int w, dev;
                vector<int> v;
                bitset<maxn> blc;
                bool operator<(const Path &p) const { return w > p.w; }
        } p, q;
        int n, s, t, w[maxn][maxn];
        bitset<maxn> blc[maxn];
        int dis[maxn], pre[maxn];
        bool vis[maxn];

        bool dijkstra(Path &ret, int d)
        {
                memset(pre, -1, sizeof(pre));
                memset(vis, false, sizeof(vis));
                memset(dis, 0x3f, sizeof(dis)); dis[s] = 0;
                for (int i = 0; i < d - 1; ++i) {
                        int u = p.v[i], v = p.v[i+1];
                        vis[u] = true; dis[v] = dis[u] + w[u][v], pre[v] = u;
                }
                for (int i = 0; i < n; ++i) {
                        int u = -1;
                        for (int v = 0; v < n; ++v) if (!vis[v])
                                if (u == -1 || dis[v] < dis[u]) u = v;
                        if (u == -1 || dis[u] == inf) break; vis[u] = true;
                        for (int v = 0; v < n; ++v) if (!vis[v]) {
                                if (blc[u][v] || blc[v][u]) continue;
                                if (dis[u] + w[u][v] < dis[v])
                                        dis[v] = dis[u] + w[u][v], pre[v] = u;
                        }
                }
                ret.w = dis[t]; ret.v.clear(); ret.blc.reset();
                for (int u = t; ~u; u = pre[u]) ret.v.push_back(u);
                reverse(ret.v.begin(), ret.v.end());
                return dis[t] != inf;
        }

        public:
        void init(int n)
        {
                this->n = n;
                memset(w, 0x3f, sizeof(w));
        }

        void add_edge(int u, int v, int w)
        {
                this->w[u][v] = w;
        }

        bool find_kth(int src, int trg, int k)
        {
                s = src, t = trg;
                priority_queue<Path> que;
                for (int u = 0; u < n; ++u) blc[u].reset();
                if (!dijkstra(p, 0)) return false;
                p.dev = 1; p.blc.set(p.v[1]); que.push(p);
                for (int i = 0; i < k; ++i) {
                        if (que.empty()) return false;
                        p = que.top(); que.pop();
                        for (int u = 0; u < n; ++u) blc[u].reset();
                        for (int d = p.dev; d < p.v.size(); ++d) {
                                int u = p.v[d-1];
                                d ^ p.dev? blc[u].set(p.v[d]): blc[u] = p.blc;
                                if (!dijkstra(q, d)) continue;
                                d ^ p.dev? q.blc.set(p.v[d]): q.blc = p.blc;
                                q.dev = d; q.blc.set(q.v[d]); que.push(q);
                        }
                }
                printf("%d %d\n", p.w, (int)p.v.size());
                for (int i = 0; i < p.v.size(); ++i)
                        printf("%d%c", p.v[i] + 1, " \n"[i==p.v.size()-1]);
                return true;
        }
} grp;

int main()
{
        int n, m, k, s, t;
        scanf("%d%d%d", &n, &m, &k);
        grp.init(n);
        while (m--) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                --u, --v;
                grp.add_edge(u, v, w);
                grp.add_edge(v, u, w);
        }
        scanf("%d%d", &s, &t);
        --s, --t;
        grp.find_kth(s, t, k);

        return 0;
}

你可能感兴趣的:(图论,sgu,Yen算法)