SGU145 Strange People

来源:互联网 发布:淘宝海外直邮快递填单 编辑:程序博客网 时间:2024/06/04 19:06

SGU145 Strange People

题目大意

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

算法思路

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

时间复杂度: O(KN3)

代码

/** * Copyright © 2015 Authors. All rights reserved. *  * FileName: 145.cpp * Author: Beiyu Li <sysulby@gmail.com> * 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;}

0 0
原创粉丝点击