【最短路】【spfa】hdu6071 Lazy Running
阿新 • • 發佈:2017-08-04
spa ima 大於 str turn set pair image pty
給你一個4個點的環,問你從2號點出發, 再回到2號點,長度>=K的最短路是多少。環上的邊長度不超過30000。
跑出來所有dis(2,j)以後,然後for一遍j,根據dis(2,j)+t*2*w>=K,解出來對於每個j而言最小的t,然後嘗試更新答案即可。如果dis(2,j)已經大於等於K了,那直接用其嘗試更新答案。
跟CDOJ1633很像。
#include<cstdio> #include<queue> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; ll ans,K; int W,T,a[4]; typedef pair<int,int> Point; queue<Point>q; bool inq[4][60010]; int dis[4][60010]; void spfa() { memset(dis,0x7f,sizeof(dis)); memset(inq,0,sizeof(inq)); q.push(make_pair(1,0)); inq[1][0]=1; dis[1][0]=0; while(!q.empty()){ Point U=q.front(); Point V=make_pair((U.first+1)%4,(U.second+a[U.first])%(2*W)); if(dis[V.first][V.second]>dis[U.first][U.second]+a[U.first]){ dis[V.first][V.second]=dis[U.first][U.second]+a[U.first]; if(!inq[V.first][V.second]){ q.push(V); inq[V.first][V.second]=1; } } V=make_pair((U.first+3)%4,(U.second+a[(U.first+3)%4])%(2*W)); if(dis[V.first][V.second]>dis[U.first][U.second]+a[(U.first+3)%4]){ dis[V.first][V.second]=dis[U.first][U.second]+a[(U.first+3)%4]; if(!inq[V.first][V.second]){ q.push(V); inq[V.first][V.second]=1; } } q.pop(); inq[U.first][U.second]=0; } } int main(){ // freopen("1005.in","r",stdin); // freopen("1005.out","w",stdout); scanf("%d",&T); for(;T;--T){ ans=9000000000000000000ll; scanf("%lld",&K); for(int i=0;i<4;++i){ scanf("%d",&a[i]); } W=min(a[1],a[0]); spfa(); for(int i=0;i<2*W;++i){ if(dis[1][i]<2000000000){ // printf("%d: (%d)\n",i,dis[1][i]); if(dis[1][i]<K){ ans=min(ans,(ll)dis[1][i]+(ll)(2*W)*((K-(ll)dis[1][i])/(ll)(2*W)+(ll)((K-(ll)dis[1][i])%(ll)(2*W)!=0))); } else{ ans=min(ans,(ll)dis[1][i]); } } } printf("%lld\n",ans); } return 0; }
【最短路】【spfa】hdu6071 Lazy Running