第k短路
题:http://poj.org/problem?id=2449
题意:
题目大意就是给出一个图,然后给出一个起点个一个终点,求这两点间的第K短路。
本题中是可以走重复的路的,所以如果一张图中有一个环的话,无论求第几短路都是存在的。
分析:
A*===优化的bfs
这里预估函数用的是该点到t的最短路值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int M=1e5+5; const int inf=0x3f3f3f3f; int tot,head[M],rhead[M],dis[M],cnt[M],vis[M]; struct E{ int v,w,nextt; }e[M],re[M]; void addedge(int u,int v,int w){ e[tot].v=v; e[tot].w=w; e[tot].nextt=head[u]; head[u]=tot; re[tot].v=u; re[tot].w=w; re[tot].nextt=rhead[v]; rhead[v]=tot++; } void spfa(int s,int n){ for(int i=0;i<=n;i++) cnt[i]=0,dis[i]=inf,vis[i]=0; queue<int>que; que.push(s); dis[s]=0; cnt[s]=1; while(!que.empty()){ int u=que.front(); que.pop(); vis[u]=0; for(int i=rhead[u];~i;i=re[i].nextt){ int v=re[i].v; if(dis[v]>dis[u]+re[i].w){ dis[v]=dis[u]+re[i].w; if(!vis[v]){ que.push(v); vis[v]=1; if(++cnt[v]>n) return ; } } } } return ; } struct node{ /*friend bool operator<(node n1,node n2){ return n1.dist>n2.dist; }*/ int x,dist; bool operator < (const node &b)const{ return this->dist>b.dist; } }; priority_queue<node>q; int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ tot=0; for(int i=0;i<=n;i++) head[i]=-1,rhead[i]=-1; while(m--){ int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } int s,t,k; scanf("%d%d%d",&s,&t,&k); spfa(t,n); if(dis[s]==inf){ puts("-1"); continue; } while(!q.empty()) q.pop(); node sta; sta.x=s,sta.dist=dis[s]; q.push(sta); int ans=-1,num=0; if(s==t) k++; while(!q.empty()){ node temp=q.top(); q.pop(); int u=temp.x; if(u==t){ num++; if(num==k){ ans=temp.dist; break; } } for(int i=head[u];~i;i=e[i].nextt){ int v=e[i].v; node close; close.x=v; close.dist=temp.dist-dis[u]+dis[v]+e[i].w; q.push(close); } } printf("%d\n",ans); } return 0; }