poj2449 Remmarguts' Date

来源:互联网 发布:云计算概念股龙头股票 编辑:程序博客网 时间:2024/05/27 06:52

典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法

k短路径的相关问题看这里,尽管已经是2007年的文章了,但作者真的写得非常详细和全面。

下面是一个简化的算法流程。

/* * k短路径 Dijkstra+A*算法 * 算法流程: * 1.将有向图的边反向后,Dijkstra求出任意节点到终点的最短路径 dis[i] * 2.优先队列  * struct * { * int v,l,d; * }priority_queue[10000]; * v:结点编号 * l:源点到v的距离 * d:源点经过v的到终点的某一条路径的长度 *  优先队列以l为权值排序 * 3.v = s,l = 0,d = 0; 入队 *  每次从优先队列中取出并去除l最小的结点 *  遍历结点v的所有后继,计算d,l并入队,不判断v的后继结点是否在队列中for(i=head[k];i;i=edge[i].next){q[++len].v = edge[i].v;q[len].d = dis[edge[i].v]+edge[i].d+q[l].l;q[len].l = q[l].l+edge[i].d;inq[len] = true;sum++;} * 4.第k次取出终点结点t,d即为第k短路径  *   可能出现同一长度的不同路径,都会被分别找出 * */

/* * poj2449 AC * k短路径 Dijkstra+A*算法 266ms * 第一次用STL,还不是很熟悉,以前都是手写二叉堆的。 * Dijkstra开始写错了,导致TLE,一天不写手生。 * 题目要注意,当终点和起点相同时,最短路径不是0,必须走一圈回来。 * */#include<stdio.h>#include<memory.h>#include<queue>#include<fstream>#include<vector>using namespace std;#define INF 100000000struct EDGE{int v,t;long next;}edge[100005],e[100005];typedef struct {long len,d;int v;}NODE;struct cmp{bool operator()(const NODE &t1,const NODE &t2){return t1.d>t2.d;}};long head[1005],h[1005];long n,m,tot,tot1;int a,b,c;long dis[1005];void Dijkstra(){bool vis[1005];NODE node,tmp;priority_queue<NODE,vector<NODE>,cmp> queue;long i,j;for(i=1;i<=n;i++){vis[i] = false;dis[i] = INF;}dis[b] = 0;node.d= 0,node.v = b;queue.push(node);for(i=1;i<=n;i++){node = queue.top();queue.pop();vis[node.v] = true;for(j=h[node.v];j;j=e[j].next)if(!vis[e[j].v] && dis[e[j].v]>dis[node.v]+e[j].t){dis[e[j].v] = dis[node.v]+e[j].t;tmp.v = e[j].v;tmp.d= dis[e[j].v];queue.push(tmp);}}while(!queue.empty())queue.pop();return;}long a_star(){NODE node,tmp;long i,num = 0;priority_queue<NODE,vector<NODE>,cmp> queue;node.len = 0,node.d = 0,node.v = a;queue.push(node);while(!queue.empty()){node = queue.top();queue.pop();if(node.v==b){num++;if(num==c) return node.d;}for(i=head[node.v];i;i=edge[i].next){tmp.v = edge[i].v;tmp.d = node.len+edge[i].t+dis[edge[i].v];tmp.len = node.len+edge[i].t;queue.push(tmp);}}return -1;}int main(){//FILE* fin;//fin = fopen("d.in","r");scanf("%ld%ld",&n,&m);//fscanf(fin,"%ld%ld",&n,&m);int i,j,k,t;memset(head,0,sizeof(head));memset(h,0,sizeof(h));tot = tot1 = 0;for(i=1;i<=m;i++){scanf("%d%d%d",&j,&k,&t);//fscanf(fin,"%d%d%d",&j,&k,&t);edge[++tot].v = k,edge[tot].t = t,edge[tot].next = head[j],head[j] = tot;e[++tot1].v = j,e[tot1].t = t,e[tot1].next = h[k],h[k] = tot1;}scanf("%d%d%d",&a,&b,&c);//fscanf(fin,"%d%d%d",&a,&b,&c);if(a==b) c++;Dijkstra();long ans;ans = a_star();printf("%ld\n",ans);return 0;}