Remmarguts' Date POJ

来源:互联网 发布:战士公主西娜 知乎 编辑:程序博客网 时间:2024/06/06 17:11

这是一道巧妙利用了A*算法的一道题

A*算法比较开心的地方是在算出最短路的时候,继续算下去会得到次最短路,继续下去是次次最短路,….所有可能的路.

在A*算法中 F(x)=G(x)+H(x)
其中G(x) 表示到x后已经走了的距离
H(x) 表示到x后再到终点估计要走多少(本题可以精确算出用SPFA)
F(x) 即是走这条路到达的期望距离

一个比较给力的剪枝 每个点访问k次就好了,多余的并没有对答案有任何的贡献
代码如下:

/* * Author       :  Echo * Email        :  1666424499@qq.com   * Description  :    * Created Time :  2017/10/5 10:36:41 * Last Modify  :  2017/10/5 20:26:55 * File Name    :  k_thRoad.cpp */#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <string>#include <vector>#include <stack>#include <queue>#include <set>#include <time.h>#define LL long long#define mem(a,k) memset(a,k,sizeof(a))using namespace std;const int maxint = -1u>>1;const int maxn=1e3+10;const int maxm=1e6+100;int H[maxn],vis[maxn];int cnt[maxn];struct node{    int f,g,s;    friend bool operator<(node a,node b){        return a.f>b.f;    }};struct edge{    int to,value,next;    void set(int a,int b,int c){        to=a,value=b,next=c;    }}an[maxm],bn[maxm];int heada[maxn],cnta,headb[maxn],cntb;int n,m;int s,t,k;void addedge(int u,int v,int value){    an[cnta].set(v,value,heada[u]);    heada[u]=cnta++;    bn[cntb].set(u,value,headb[v]);    headb[v]=cntb++;}void getH(){//spfa    for(int i=0;i<=n;i++) H[i]=1e9;    H[t]=0;    vis[t]=1;    queue<int> que;    que.push(t);    while(!que.empty()){        int u=que.front();        que.pop();        vis[u]=0;        for(int i=headb[u];i!=-1;i=bn[i].next){            int v=bn[i].to;            if(H[v]>H[u]+bn[i].value){                H[v]=H[u]+bn[i].value;                if(!vis[v])que.push(v),vis[v]=1;            }        }    }}int A_star(){    getH();    //for(int i=1;i<=n;i++){        //printf("%d ",H[i]);    //}    //cout<<endl;    priority_queue<node>que;    node now;    now.g=0;    now.s=s;    now.f=now.g+H[now.s];    que.push(now);    while(!que.empty()){        now=que.top();        que.pop();        cnt[now.s]++;        if(cnt[now.s]>k) continue;        //printf("test 1:%d %d %d\n",now.s,now.g,now.f);        node nxt;        if(now.s==t&&cnt[now.s]==k)return now.f;        for(int i=heada[now.s];i!=-1;i=an[i].next){            if(H[an[i].to]==1e9)continue;            nxt.g=now.g+an[i].value;            nxt.s=an[i].to;            nxt.f=nxt.g+H[nxt.s];            //printf("test 2:%d %d %d\n",nxt.s,nxt.g,nxt.f);            que.push(nxt);        }    }    return -1;}int main(){    cin>>n>>m;    memset(heada,-1,sizeof(heada));    memset(headb,-1,sizeof(headb));    for(int i=1;i<=m;i++){        int a,b,v;        scanf("%d%d%d",&a,&b,&v);        addedge(a,b,v);    }    scanf("%d%d%d",&s,&t,&k);    if(s==t)k++;    printf("%d",A_star());    return 0;}/*7 81 2 22 4 24 5 25 7 21 3 23 2 24 6 12 1 21 1 2 */
原创粉丝点击