第k短路

题:http://poj.org/problem?id=2449

题意:

  题目大意就是给出一个图,然后给出一个起点个一个终点,求这两点间的第K短路。

  本题中是可以走重复的路的,所以如果一张图中有一个环的话,无论求第几短路都是存在的。

分析:

  A*===优化的bfs

  这里预估函数用的是该点到t的最短路值。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=1e5+5;
const int inf=0x3f3f3f3f;
int tot,head[M],rhead[M],dis[M],cnt[M],vis[M];
struct E{
    int v,w,nextt;
}e[M],re[M];
void addedge(int u,int v,int w){
    e[tot].v=v;
    e[tot].w=w;
    e[tot].nextt=head[u];
    head[u]=tot;
    re[tot].v=u;
    re[tot].w=w;
    re[tot].nextt=rhead[v];
    rhead[v]=tot++;
}
void spfa(int s,int n){
    for(int i=0;i<=n;i++)
        cnt[i]=0,dis[i]=inf,vis[i]=0;
    queue<int>que;
    que.push(s);
    dis[s]=0;
    cnt[s]=1;
    while(!que.empty()){
        int  u=que.front();
        que.pop();
        vis[u]=0;
        for(int i=rhead[u];~i;i=re[i].nextt){
            int v=re[i].v;
            if(dis[v]>dis[u]+re[i].w){
                dis[v]=dis[u]+re[i].w;
                if(!vis[v]){
                    que.push(v);
                    vis[v]=1;
                    if(++cnt[v]>n)
                        return ;
                }
            }
        }
    }
    return ;
}
struct node{
    /*friend bool operator<(node n1,node n2){
        return n1.dist>n2.dist;
    }*/
    int x,dist;
    bool operator < (const node &b)const{
        return this->dist>b.dist;
    }
};
priority_queue<node>q;
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        tot=0;
        for(int i=0;i<=n;i++)
            head[i]=-1,rhead[i]=-1;
        while(m--){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
        }
        int s,t,k;
        scanf("%d%d%d",&s,&t,&k);
        spfa(t,n);
        if(dis[s]==inf){
            puts("-1");
            continue;
        }
        while(!q.empty())
            q.pop();
        node sta;
        sta.x=s,sta.dist=dis[s];
        q.push(sta);
        int ans=-1,num=0;
        if(s==t)
            k++;
        while(!q.empty()){
            node temp=q.top();
            q.pop();
            int u=temp.x;
            if(u==t){
                num++;
                if(num==k){
                    ans=temp.dist;
                    break;
                }
            }
            for(int i=head[u];~i;i=e[i].nextt){
                int v=e[i].v;
                node close;
                close.x=v;
                close.dist=temp.dist-dis[u]+dis[v]+e[i].w;
                q.push(close);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code
posted @ 2019-12-27 21:41  starve_to_death  阅读(121)  评论(0编辑  收藏  举报