POJ 2449 Remmarguts' Date(k短路)
2017-11-07 20:06
246 查看
题面
题意
给出一幅有向图,求出其中的第k短路方法
首先应该想到用BFS加上优先队列,按照距离由短到长进行搜索,当到达终点次数达到k次时停止.代码(错误)
#include<iostream&g 4000 t; #include<cstdio> #include<cstring> #include<queue> #define ll long long #define P pair<ll,ll> #define fi first #define se second #define N 1010 #define M 100100 using namespace std; struct Bn { ll next,to,time; }bn[M]; ll n,m,k,first ,bb,s,t; priority_queue<P,vector<P>,greater<P> >pq; P tmp; void add(ll u,ll v,ll w) { bb++; bn[bb].to=v; bn[bb].next=first[u]; bn[bb].time=w; first[u]=bb; } int main() { ll i,j,p,q,o; P now; memset(first,-1,sizeof(first)); for(;!pq.empty();pq.pop()); cin>>n>>m; for(i=1;i<=n;i++) { scanf("%lld%lld%lld",&p,&q,&o); add(p,q,o); } cin>>s>>t>>k; tmp.fi=0; tmp.se=s; pq.push(tmp); for(;!pq.empty();) { tmp=pq.top(); pq.pop(); if(tmp.se==t) { if(k==1) { printf("%lld",tmp.first); return 0; } k--; } now=tmp; p=first[now.se]; for(;p!=-1;p=bn[p].next) { tmp.fi=now.fi+bn[p].time; tmp.se=bn[p].to; pq.push(tmp); } } printf("-1"); return 0; }
这种方法有以下缺点:
1.上述思路占用空间过大,会爆队列
2.当遇到无法到达终点时的情况就会陷入死循环
我们先解决第二个问题
要求k短路,则每个点最多扫过k次,因而我们可以记录每个点走过的次数,若超过k则跳过这个点,则不仅可解决上述问题,还能起到剪枝作用
对于第一个问题则需要改变排序的方式,因为目标是t,则可以根据到达t的最短需要长度进行排序,而不是根据已经经过路径,若根据已经经过路径长度排序,则可能会多次搜索离t较远的点,浪费大量空间.
为了计算出到达t的最短路,可以以t为起点,用迪杰斯特拉算出每一点到达它的最小距离(因点数少,边数多,可以用邻接矩阵),重定义一下小于号即可.
另外还要注意当起点和终点重合时,应该让k+1,因为一开始到达的那一次不算
代码(正解)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define N 2010 #define M 200200 #define INF 0x3f3f3f3f using namespace std; int n,m,k,first ,bb,s,t,cnt ,d ,mm ; struct Bn { int next,to,time; } bn[M]; struct Dn { int len,pos; bool operator < (const Dn &u) const { return len + d[pos] > u.len + d[u.pos]; } }; priority_queue<Dn>pq; bool vis ; Dn tmp,now; inline void add(int u,int v,int w) { bb++; bn[bb].to=v; bn[bb].next=first[u]; bn[bb].time=w; first[u]=bb; } inline void gx(int u) { int i; for(i=1; i<=n; i++) { if(vis[i]) continue; if(d[i]>mm[i][u]+d[u]) { d[i]=mm[i][u]+d[u]; } } } inline void get() { int i,j,l,mn; d[t]=0; vis[t]=1; gx(t); for(i=1; i<=n; i++) { mn=INF; l=0; for(j=1; j<=n; j++) { if(vis[j]) continue; if(d[j]<mn) { l=j; mn=d[j]; } } if(!l) return; vis[l]=1; gx(l); } } int main() { // freopen("1.txt","r",stdin); int i,j,p,q,o; memset(first,-1,sizeof(first)); memset(d,INF,sizeof(d)); memset(mm,INF,sizeof(mm)); for(;!pq.empty();pq.pop()); scanf("%d%d",&n,&m); for(i=1; i<=m; i++) { scanf("%d%d%d",&p,&q,&o); add(p,q,o); mm[p][q]=min(mm[p][q],o); } scanf("%d%d%d",&s,&t,&k); k+= s==t; get(); if(!vis[s]) { printf("-1\n"); return 0; } tmp.pos=s; tmp.len=0; pq.push(tmp); for(; !pq.empty();) { now=pq.top(); pq.pop(); cnt[now.pos]++; if(cnt[t]==k) { printf("%d\n",now.len); return 0; } if(cnt[now.pos]>k) continue; for(p=first[now.pos] ; p!=-1; p=bn[p].next) { tmp.len=now.len+bn[p].time; tmp.pos=bn[p].to; pq.push(tmp); } } printf("-1\n"); }
相关文章推荐
- POJ 2449 Remmarguts' Date ( Dijkstra + A* 求解第K短路 )
- POJ 2449 Remmarguts' Date A*+spfa求第k最短路
- POJ 2449 Remmarguts' Date【K短路】
- POj 2449 Remmarguts' Date K短路 A*+SPFA
- (poj 2449 Remmarguts' Date)<A*-K短路模板>
- POJ 2449 Remmarguts' Date [第k短路]
- 【K短路】【A星】Remmarguts' Date POJ 2449 A-Star
- poj2449 Remmarguts' Date A*K短路
- POJ 2449 Remmarguts' Date 第K短路 A*
- POJ 2449 Remmarguts' Date 求K短路
- poj--2449 Remmarguts' Date(k短路)
- poj2449 Remmarguts' Date,第K短路
- POJ 2449 Remmarguts' Date 第k短路 A*搜索
- poj_2449 Remmarguts' Date(第k短路+Dijkstra+A*)
- 【POJ 2449】Remmarguts' Date(A*+dij求k短路)
- poj2449 Remmarguts' Date(K短路:A*算法)
- [A* K短路] POJ 2449 Remmarguts' Date
- poj 2449 Remmarguts' Date(第K短路)
- POJ 2449 Remmarguts' Date(A* - 第K短路)
- POJ 2449 Remmarguts' Date (第k短路 A*搜索算法模板)