poj 2449 k短路

来源:互联网 发布:苏州青旅 知乎 编辑:程序博客网 时间:2024/06/01 21:11

一道给定图,求S->T的k短路,想了半天还是没想法,看了别人题解才懂得,先求反向图源点为t的最短路,我是用dij的优先队列写的。然后用对于正向图,利用ASTAR算法,

利用优先队列,估价函数为f[i]=w+d[i],意思就是,我走了一个距离w,还有最短d[i]距离再到k,满足d[i]<=实际代价,ASTAR算法成立,这样对于每个节点,把所有与之相邻的点,压入优先队列,这样访问到节点t第k次时为k短路,返回此时的w,里面一个剪纸,对于一个点访问了大于k次就直接continue,因为这样走下去,肯定为>k短路。

code:

#include<cstdio>#include<cstring>#include<queue>#include<vector>using namespace std;int n,m,s,t,k,d[1010],find[1010],cnt[1010];const int inf=999999999;struct node{int y,l;};struct dij{int v,w;friend bool operator<(dij a,dij b){return a.w>b.w;}};struct aastar{int v,w;friend bool operator<(aastar a,aastar b){return a.w+d[a.v]>b.w+d[b.v];}};vector<node>vt[1010];vector<node>rvt[1010];void dijstra(){for(int i=1;i<=n;i++)d[i]=inf;d[t]=0;memset(find,0,sizeof(find));priority_queue<dij>q;dij ss,tt;ss.v=t;ss.w=0;q.push(ss);while(!q.empty()){ss=q.top();q.pop();int v=ss.v;int w=ss.w;find[v]=1;for(int i=0;i<rvt[v].size();i++){int y=rvt[v][i].y;int l=rvt[v][i].l;if(!find[y]&&d[y]>d[v]+l){d[y]=d[v]+l;tt.v=y;tt.w=d[y];q.push(tt);}}}}int Astar(){memset(cnt,0,sizeof(cnt));aastar ss,tt;ss.v=s,ss.w=0;if(d[s]==inf)return -1;if(s==t)k++;priority_queue<aastar>q;q.push(ss);while(!q.empty()){ss=q.top();q.pop();int v=ss.v;int w=ss.w;if(v==t){cnt[t]++;if(cnt[t]==k)return w;}elsecnt[v]++;if(cnt[v]>k)continue;for(int i=0;i<vt[v].size();i++){int y=vt[v][i].y;int l=vt[v][i].l;tt.v=y,tt.w=w+l;q.push(tt);}}return -1;}int main(){while(2==scanf("%d%d",&n,&m)){int a,b,c;for(int i=1;i<=n;i++){vt[i].clear();rvt[i].clear();}for(int i=0;i<m;i++){scanf("%d%d%d",&a,&b,&c);node s;s.y=b,s.l=c;vt[a].push_back(s);s.y=a;rvt[b].push_back(s);}scanf("%d%d%d",&s,&t,&k);dijstra();printf("%d\n",Astar());}return 0;}


原创粉丝点击