bzoj1598: [Usaco2008 Mar]牛跑步
很久之前被ozyD去做妙的时候学的k短路,结果妙没做出来,k短路还忘了。。。把A*温了一下。
其实很好理解,先用spfa建出反图,然后dij,不想讲就搞个板子吧。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> using namespace std; int n,m,k; struct node { int x,y,d,next; }a[510000],b[510000]; int len1,last1[11000],len2,last2[11000]; void ins1(int x,int y,int d) { len1++; a[len1].x=x;a[len1].y=y;a[len1].d=d; a[len1].next=last1[x];last1[x]=len1; } void ins2(int x,int y,int d) { len2++; b[len2].x=x;b[len2].y=y;b[len2].d=d; b[len2].next=last2[x];last2[x]=len2; } //------------------------------------ int d[11000],list[11000]; bool v[11000]; void SPFA() { memset(d,63,sizeof(d));d[1]=0; memset(v,false,sizeof(v));v[1]=true; int head=1,tail=2;list[1]=1; while(head!=tail) { int x=list[head]; for(int k=last2[x];k;k=b[k].next) { int y=b[k].y; if(d[y]>d[x]+b[k].d) { d[y]=d[x]+b[k].d; if(v[y]==false) { v[y]=true; list[tail]=y; tail++;if(tail==10000)tail=1; } } } v[x]=false; head++;if(head==10000)head=1; } } //------------spfa------------------- struct As { int f,g,v;//f==d[x]+g,用来维护优先队列 g表示出发走了多少距离,v相当于边目录的y friend bool operator<(As n1,As n2) { if(n1.f==n2.f)return n1.g>n2.g; return n1.f>n2.f; } }; priority_queue<As>Q; void A_star() { int cnt=0;As x,y; x.v=n,x.g=0,x.f=x.g+d[n];Q.push(x); while(Q.empty()==false) { x=Q.top();Q.pop(); if(x.v==1) { cnt++; printf("%d\n",x.g); if(cnt==k)return ; } for(int k=last1[x.v];k;k=a[k].next) { y.v=a[k].y; y.g=x.g+a[k].d; y.f=y.g+d[y.v]; Q.push(y); } } for(int i=cnt;i<k;i++)printf("-1\n"); } //-------------dij---------------------- int main() { int x,y,d; scanf("%d%d%d",&n,&m,&k); len1=0;memset(last1,0,sizeof(last1)); len2=0;memset(last2,0,sizeof(last2)); for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&d); ins1(x,y,d);ins2(y,x,d); } SPFA(); A_star(); return 0; }
pain and happy in the cruel world.