POJ2449

来源:互联网 发布:手机广告平面设计软件 编辑:程序博客网 时间:2024/06/05 23:52

Problem: Remmarguts’ Date
Description: 给你一个图,让你寻找第K短的路径从src点到des点。
Solution: A* +邻接表的迪杰斯特拉。这题目是ACM/ICPC上的一道例题。我用来加深了对A* 算法的理解和对邻接表的迪杰斯特拉的学习。我们先用迪杰斯特拉算法求出每一个点到des的距离用来当做评估条件,然后用A* 算法从src向下广搜。由于A* 算法有这朝最短路方向搜索的趋势,那么当第K次到达des时,这个时候的距离就是第K短路。代码是我自己理解后自己敲的。
Code(C++):

#include <stdio.h>#include <string.h>#include <queue>#define INF 0x3f3f3f3fusing namespace std;const int M=100005;bool used[M];int dis[M];int head_a[M],head_b[M];typedef struct tagEdge{    int from,to;    int value;    int next;    tagEdge(){}    tagEdge(int _from,int _to,int _value,int _next):        from(_from),to(_to),value(_value),next(_next){}}Edge;typedef struct tagNode{    int to;    int value;    tagNode(){}    tagNode(int _to,int _value):        to(_to),value(_value){}    bool operator<(const tagNode &other)const{        return value+dis[to]>other.value+dis[other.to];    }}Node;Edge edges_a[M],edges_b[M];int n,m;int edges_num;int src,des,k;void init(){    edges_num=0;    memset(head_a,-1,sizeof(head_a));    memset(head_b,-1,sizeof(head_b));}void add_edge(Edge *p,int *hd,int x,int y,int c){    p[edges_num]=Edge(x,y,c,hd[x]);    hd[x]=edges_num;}void dij(int des,Edge* edge,int *head){    memset(used,false,sizeof(used));    for(int i=1;i<=n;i++)        dis[i]=INF;    dis[des]=0;    priority_queue<Node> que;    que.push(Node(des,0));    for(int i=1;i<n;i++){        while(!que.empty()&&used[que.top().to])            que.pop();        if(que.empty())            break;        Node now=que.top();        que.pop();        used[now.to]=true;        for(int j=head[now.to];j+1;j=edge[j].next)            if(!used[edge[j].to]&&dis[edge[j].to]>dis[now.to]+edge[j].value){                dis[edge[j].to]=dis[now.to]+edge[j].value;                que.push(Node(edge[j].to,0));            }    }}int a_star(int src,Edge *edge,int *head){    priority_queue<Node> que;    que.push(Node(src,0));    while(!que.empty()){        Node now=que.top();        que.pop();        if(now.to==des){            if(!k)                return now.value;            --k;        }        for(int i=head[now.to];i+1;i=edge[i].next)            que.push(Node(edge[i].to,now.value+edge[i].value));    }    return -1;}int main(){    while(~scanf("%d%d",&n,&m)){        init();        int x,y,c;        while(m--){            scanf("%d%d%d",&x,&y,&c);            add_edge(edges_a,head_a,x,y,c);            add_edge(edges_b,head_b,y,x,c);            ++edges_num;        }        scanf("%d%d%d",&src,&des,&k);        dij(des,edges_b,head_b);        if(dis[src]>=INF){            puts("-1");            continue;        }        if(src==des)            ++k;        --k;        int ans=a_star(src,edges_a,head_a);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击