1. 程式人生 > >bzoj 2259 [Oibh] 新型計算機 —— 最短路

bzoj 2259 [Oibh] 新型計算機 —— 最短路

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=2259

相鄰點之間連邊權為1的邊,就是水最短路了;

要注意點上的數不能改成負數,但是想一想改成負數還不如一開始就不走到這個點,所以這個不必擔心;

注意1號點到2號點不能連邊權為1的邊,因為實際上不能直接走過去。

程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace
std; typedef long long ll; int const xn=1e6+5; int n,hd[xn],ct,to[xn*3],nxt[xn*3],w[xn*3]; ll dis[xn]; bool vis[xn]; struct N{ ll d; int id; bool operator < (const N &y) const {return d>y.d;} }; priority_queue<N>q; int rd() { int ret=0,f=1; char ch=getchar(); while(ch<'0'
||ch>'9'){if(ch=='-')f=0; ch=getchar();} while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar(); return f?ret:-ret; } void add(int x,int y,int z){to[++ct]=y; nxt[ct]=hd[x]; w[ct]=z; hd[x]=ct;} void dij() { memset(dis,0x3f,sizeof dis); dis[1]=0; q.push((N){0,1
}); while(q.size()) { int x=q.top().id; q.pop(); if(vis[x])continue; vis[x]=1; for(int i=hd[x],u;i;i=nxt[i]) if(dis[u=to[i]]>dis[x]+w[i]) dis[u]=dis[x]+w[i],q.push((N){dis[u],u}); } } int main() { n=rd(); for(int i=1,x;i<=n;i++) { x=rd(); if(i+x+1<=n+1)add(i,i+x+1,0); else add(i,n+1,i+x-n); if(i>1)add(i,i+1,1);//i>1 if(i>1)add(i,i-1,1); } dij(); printf("%lld\n",dis[n+1]); return 0; }