POJ 2449 Remmarguts' Date(A* - 第K短路)

来源:互联网 发布:魔方淘宝网 编辑:程序博客网 时间:2024/05/19 04:02

题意:找第K短路的值

思路:A*,bfs找K短路的时候加上估计函数(距离下界),而且要满足:cost(u,v)+h*(u)-h*(v)>=0

因为这是bfs'需要的下界函数,不是任何下界都可以,不像IDA*,这里的下界必须让每个bfs的节点保持原样的大小关系

而IDDFA中的A*下界函数就不需要这个性质了,只要是下界即可。

显然这个具体问题的天然的估计函数就是从此点到目标点的最短路。

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int M =1e5+100;const int N =1e3+10;const int inf = 0x3f3f3f3f ;struct Edge{    int v;    int w;    int next;}es1[M],es2[M];int head1[N],head2[N];int n,m;int s,g,k;bool vis[N];int dis[N];void spfa(){    memset(vis,0,sizeof(vis));    dis[g]=0;    queue<int >q;    q.push(g);    vis[g]=true;    while(!q.empty())    {        int cur=q.front();        q.pop();        vis[cur]=false;        for(int i=head2[cur];~i;i=es2[i].next)        {            int v=es2[i].v,w=es2[i].w;            if(dis[v]>dis[cur]+w)            {                dis[v]=dis[cur]+w;                if(vis[v]) continue;                vis[v]=true;                q.push(v);            }        }    }}struct node{    int u;    int g,f;    bool operator < (const node &a) const    {        return a.f<f; //按f最小堆    }};int A_star(){    int cnt=0;    priority_queue<node> que;    if(dis[s]==inf) return -1;  //剪枝    node st;    st.g=0,st.f=dis[s],st.u=s;    que.push(st);    while(!que.empty())    {        node cur=que.top();        que.pop();        if(cur.u==g) cnt++;        if(cnt==k) return cur.g;        for(int i=head1[cur.u];~i;i=es1[i].next)        {            int v=es1[i].v,w=es1[i].w;            node nxt;            nxt.u=v,nxt.g=cur.g+w,nxt.f=nxt.g+dis[v];            que.push(nxt);        }    }    return -1;}void ini(){    fill(dis,dis+1005,inf);    memset(head1,-1,sizeof(head1));    memset(head2,-1,sizeof(head2));}int main(){    while(~scanf("%d%d",&n,&m))    {        ini();        for(int i=1;i<=m;i++)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            es1[i].v = v,es1[i].w=w,es1[i].next=head1[u];            head1[u]=i;            es2[i].v=u,es2[i].w=w,es2[i].next=head2[v];            head2[v]=i;        }        scanf("%d%d%d",&s,&g,&k);        if(s==g) k++;   //易错,当s和g重合时,没经过其他路不算一种方法        spfa();        printf("%d\n",A_star());    }    return 0;}


0 0