[poj2449]Remmarguts' Date(K短路模板题,A*算法)

解题关键:k短路模板题,A*算法解决。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1e3+10;
const int M=1e5+10;
const int inf=1e9;
struct edge{
    int v,w,nxt;
}e1[M],e2[M];
struct node{
    int id;///当前节点编号
    int f;//f表示经过当前节点的最短路,f=g+h
    int g;//g表示S->当前节点的最短路
    node(int id=0,int f=0,int g=0):id(id),f(f),g(g){}
    bool operator<(const node &a)const{
        if(f==a.f) return g>a.g;
        return f>a.f;
    }
};
bool vis[N];
int tot,head1[N],head2[N],n,m,K;
int dis[N];//dis[i]表示当前点i到终点T的最短路径
void add_edge(int u,int v,int w){
    e1[tot].v=v;e1[tot].w=w;e1[tot].nxt=head1[u];head1[u]=tot;
    e2[tot].v=u;e2[tot].w=w;e2[tot].nxt=head2[v];head2[v]=tot;
    tot++;
}//两个图
void spfa(int S){//更新每个点->n点的最短距离
    queue<int>q;
    fill(dis,dis+n+1,inf);
    dis[S]=0;
    vis[S]=1;
    q.push(S);
    while(!q.empty()){
        int x=q.front();q.pop();
        vis[x]=0;
        for(int i=head2[x];~i;i=e2[i].nxt){
            int v=e2[i].v,w=e2[i].w;
            if(dis[v]>dis[x]+w){
                dis[v]=dis[x]+w;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}
int A_Star(int S,int T){
    if(S==T) K++;//坑,题目要求必须走,s==t路程可能为0,所以K要加1
    priority_queue<node>q;
    q.push(node(S,0,0));
    int cnt=0;
    while(!q.empty()){
        node h=q.top();q.pop();
        if(h.id==T){
            if(++cnt==K){
                return h.f;
            }
        }
        for(int i=head1[h.id];~i;i=e1[i].nxt){
            q.push(node(e1[i].v,h.g+e1[i].w+dis[e1[i].v],h.g+e1[i].w));//最短路更新k短路
        }
    }
    return -1;
}
int main(){
    memset(head1,-1,sizeof head1);
    memset(head2,-1,sizeof head2);
    scanf("%d%d",&n,&m);
    for(int i=1,x,y,z;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        add_edge(x,y,z);
    }
    int S,T;
    scanf("%d%d%d",&S,&T,&K);
    spfa(T);//预处理,反向遍历
    int ans=A_Star(S,T);
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/elpsycongroo/p/10360641.html