1. 程式人生 > >bzoj1598: [Usaco2008 Mar]牛跑步

bzoj1598: [Usaco2008 Mar]牛跑步

pos %d tor -- 表示 eof 走了 理解 esp

很久之前被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; }

bzoj1598: [Usaco2008 Mar]牛跑步