k短路

复杂度好像很乱,用了A_star不好算.要看估值函数.但是一般适用于N<=1000的

#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxe = 10005;
const int maxn = 1005;
const int inf = 0x3f3f3f3f;

struct node2 {
    int to;
    int g, f; // f = g + h
    bool operator < (const node2 &a) const {
        if (f != a.f) return f > a.f;
        return g > a.g;
    }
    node2() { }
    node2(int tt, int gg, int ff) : to(tt), g(gg), f(ff) { }
};

struct Edge {
    int lst;
    int to;
    int w;
}edge[maxe], redge[maxe];
int head[maxn], rhead[maxn];
int qsz, rqsz;
int dist[maxn];
bool vis[maxn];

inline void add(int u, int v, int w) {
    edge[qsz].lst = head[u];
    edge[qsz].to  = v;
    edge[qsz].w   = w;
    head[u] = qsz++;
    
    redge[rqsz].lst = rhead[v];
    redge[rqsz].to  = u;
    redge[rqsz].w   = w;
    rhead[v] = rqsz++;    
}

void spfa(int st) {
    int u, i, v;
    queue<int> q;
    memset(dist, 0x3f, sizeof(dist));
    memset(vis , 0, sizeof( vis));
    dist[st] = 0;
    q.push(st);
    vis[st] = true;
    while (!q.empty()) {
        u = q.front(); q.pop(); vis[u] = false;
        for (i=rhead[u]; i; i=redge[i].lst) {
            v = redge[i].to;
            if (dist[v] > dist[u]+redge[i].w) {
                dist[v] = dist[u]+redge[i].w;
                if (vis[v]) continue;
                q.push(v);
                vis[v] = true;
            }
        }
    }
}

int a_star(int st, int ed, int k) {
    int i, cnt = 0;
    node2 now;
    priority_queue<node2> pq;
    if (st == ed) k++;
    if (dist[st] == inf) return -1;
    pq.push(node2(st, 0, dist[st])); // f = g + h;
    while (!pq.empty()) {
        now = pq.top(); pq.pop();
        if (now.to == ed) cnt++;
        if (cnt == k) return now.g;
        for (i=head[now.to]; i; i=edge[i].lst) 
            pq.push(node2(edge[i].to, now.g+edge[i].w, now.g+edge[i].w+dist[edge[i].to]));
    }
    return -1;
}

int main()
{
    int n, m, i, j;
    int s, e, k, t;
    int u, v, w;
    while (scanf("%d%d", &n, &m) != EOF) {
        rqsz = qsz = 1;
        memset(head, 0, sizeof(head));
        memset(rhead, 0, sizeof(rhead));
        
        scanf("%d%d%d%d", &s, &e, &k, &t);
        for (i=1; i<=m; ++i) {
            scanf("%d%d%d", &u, &v, &w);
            add(u, v, w);
        }
        spfa(e);
        int res = a_star(s, e, k);
        if (res<=t && res!=-1) puts("yareyaredawa");
        else puts("Whitesnake!");
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/cgjh/p/9771701.html