poj2449 Remmarguts' Date

来源:互联网 发布:大恒视觉软件 编辑:程序博客网 时间:2024/06/16 11:15

这题题意为给一张有向图,还有起点s,终点e,求s到e的第k短的路。

思路:此题要用到A*算法,先求反向的从终点e到各个点的最短路径,定义结构体

struct node{  int p,h,g;  bool operator <(const node a)const {    return g+h<a.g+a.h; }}

即p为该点,h为从原点走到p的已花费代价,g为预估到终点的花费,即p到终点的最短路。
在bfs的过程中如果一个点被出队k次,即求出原点到该点的第k短路。
而且该题的主要目的是给大家一个较好的基于邻接表的dijstra优先队列实现算法。
代码如下:

#include <cstdio>#include <algorithm>#include <queue>#include <vector>#include <cstring>#include <iostream>#define INF 0x3f3f3f3fusing namespace std;const int maxn=1010;int n,m,s,e,k;int time[1010];struct Edge {  int from, to, dist;  Edge(int u, int v, int d):from(u),to(v),dist(d) {}};struct HeapNode {  int d, u;  bool operator < (const HeapNode& rhs) const {    return d > rhs.d;}};struct node{    int p,g,h;    bool operator <(const node &a) const    {        return g+h>a.g+a.h;    }};struct Dijkstra {  int n, m;  vector<Edge> edges;  vector<int> G[maxn];  bool done[maxn];  int d[maxn];  int p[maxn];void init(int n) {    this->n = n;    for(int i = 0; i <= n; i++) G[i].clear();    edges.clear();  }  void AddEdge(int from, int to, int dist) {    edges.push_back(Edge(from, to, dist));    m = edges.size();    G[from].push_back(m-1);  }void dijkstra(int s) {  priority_queue<HeapNode> Q;  for(int i = 1; i <= n; i++) d[i] = INF;  d[s] = 0;  memset(done, 0, sizeof(done));  Q.push((HeapNode){0, s});  while(!Q.empty()) {    HeapNode x = Q.top(); Q.pop();    int u = x.u;    if(done[u]) continue;    done[u] = true;    for(unsigned int i = 0; i < G[u].size(); i++) {      Edge& e = edges[G[u][i]];      if(d[e.to] > d[u] + e.dist) {        d[e.to] = d[u] + e.dist;        p[e.to] = G[u][i];        Q.push((HeapNode){d[e.to], e.to});      }    }  }}}dij,bd;int bfs(){    priority_queue<node> q;    node start;    start.p=s,start.h=0,start.g=0;    q.push(start);    int cost=-1;    while(!q.empty())    {        node temp=q.top();        q.pop();        time[temp.p]++;        if(time[temp.p]==k&&temp.p==e)        {            cost=temp.h+temp.g;            break;        }        if(time[temp.p]>k)        {            continue;        }        for(unsigned int i=0;i<bd.G[temp.p].size();i++)        {            node temp1;            temp1.p=bd.edges[bd.G[temp.p][i]].to;            temp1.h=bd.edges[bd.G[temp.p][i]].dist+temp.h;            temp1.g=dij.d[temp1.p];            q.push(temp1);        }    }    return cost;}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(time,0,sizeof(time));        dij.init(n);        bd.init(n);        for(int i=0;i<m;i++)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            dij.AddEdge(v,u,w);            bd.AddEdge(u,v,w);        }        scanf("%d%d%d",&s,&e,&k);        dij.dijkstra(e);        if(s==e)            k++;        int cost=bfs();        cout<<cost<<endl;    }}
0 0