标签:rmi rom using res connect ini text nes pre
Time Limit: 4000MS | Memory Limit: 65536K | |
Total Submissions: 30772 | Accepted: 8397 |
Description
Input
Output
Sample Input
2 2 1 2 5 2 1 4 1 2 2
Sample Output
14
边可以重复走,
不严格的k短路
A*
估价函数为dis(起点,i)+dis(i,终点)
1、反向图上求出终点到每个点的最短路
2、起点入优先队列,
队首出队,
如果队首是终点,而且是第k次出队,
那么当前距离就是k短路
如果队首不是终点,便利与当前点连接的所有的点,入队
细节1:优先队列出入队不用vis数组判重,因为边可以重复走
细节2:如果第1步中,起点与终点不连通,输出-1结束,
否则进入A*,没有vis数组,出现环会死循环
细节3:如果起点=终点,令k++,因为起点会立即出队
#include<queue> #include<cstdio> #include<cstring> #define N 1001 #define M 100001 using namespace std; int n,s,t,k; int dis1[N]; bool vis[N]; int front[N],to[M],nxt[M],val[M],tot; int front2[N],to2[M],nxt2[M],val2[M],tot2; struct node { int num,dis; bool operator < (node p) const { return dis+dis1[num]>p.dis+dis1[p.num]; } }now,nt; void add(int u,int v,int w) { to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w; to2[++tot2]=u; nxt2[tot2]=front2[v]; front2[v]=tot2; val2[tot2]=w; } void init() { int m,u,v,w; scanf("%d%d",&n,&m); while(m--) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); } scanf("%d%d%d",&s,&t,&k); } void spfa() { memset(dis1,63,sizeof(dis1)); queue<int>q; dis1[t]=0; vis[t]=true; q.push(t); int now; while(!q.empty()) { now=q.front(); q.pop(); vis[now]=false; for(int i=front2[now];i;i=nxt2[i]) if(dis1[to2[i]]>dis1[now]+val2[i]) { dis1[to2[i]]=dis1[now]+val2[i]; if(!vis[to2[i]]) { q.push(to2[i]); vis[to2[i]]=true; } } } } void Astar() { if(dis1[s]>1e9) { printf("-1"); return; } if(s==t) k++; int cnt=0,last=-1; priority_queue<node>q; now.num=s; now.dis=0; q.push(now); while(!q.empty()) { now=q.top(); q.pop(); if(now.num==t) { cnt++; if(cnt==k) { printf("%d",now.dis); return; } } for(int i=front[now.num];i;i=nxt[i]) { nt.num=to[i]; nt.dis=now.dis+val[i]; q.push(nt); } } printf("-1"); } int main() { init(); spfa(); Astar(); }
poj 2449 Remmarguts' Date (k短路模板)
标签:rmi rom using res connect ini text nes pre
原文地址:http://www.cnblogs.com/TheRoadToTheGold/p/7421265.html