Vijos——T 1082 丛林探险
https://vijos.org/p/1082
描述
东非大裂谷中有一片神秘的丛林,是全世界探险家的乐园,著名黄皮肤探险家BB一直想去试试。正好我国科学家2005年4月将首次对东非大裂谷进行科考,BB决定随科考队去神秘丛林探险。在出发之前,他搜集了国内外有关神秘丛林探险的资料,并绘制成一张地图:该地图上有若干安全点(包括入口点和出口点),并将这些安全点编号为1、2、…、n;如果一个安全点和另一个安全点有一条路直接相通,则用一条边标示;该图是一个连通图(任意两点间有至少一条路径),地图上每条路的长度和走这条路需要耗费的体力都做了标示。
KK行走速度为1,并知道自己体力为K。他想知道根据自己的体力情况能否成功地穿过丛林。
格式
输入格式
第一行两个整数n(<=5000) m(<=40000),分别表示地图上安全点的个数和边的数目;
第2行至第m+1 行每行4个整数x y c d,x、y表示有直接相联边的两个点的编号,c走这条路需要耗费的体力;d表示边的长度;(其中150<=c,d<=300)
第m+2行两个整数s t,分别表示安全的入口点和出口点的编号;
第m+3行一个整数k,表示BB的体力值;(K<10^9)
同一行上的多个数据用空格隔开。
输出格式
一个整数,如果BB能安全地从如入口穿过丛林到达出口,输出最短时间,否则输出-1
样例1
样例输入1
4 5
1 2 2 3
1 3 3 5
1 4 7 10
2 4 4 6
3 4 2 6
1 4
5
样例输出1
11
限制
各个测试点1s
要求输出最小时间,可以在SPFA判断时 加一个目前消耗体力<总体力
1 #include <cstdio> 2 #include <queue> 3 4 #define min(a,b) (a<b?a:b) 5 #define INF (1<<30) 6 7 using namespace std; 8 9 const int M(40000+5); 10 const int N(5000+15); 11 int n,m,u,v,ups,dis,s,t,tps; 12 13 int head[N],sumedge; 14 struct Edge 15 { 16 int u,v,wp,wd,nx; 17 Edge(int u=0,int v=0,int nx=0,int wp=0,int wd=0): 18 u(u),v(v),nx(nx),wp(wp),wd(wd){} 19 }edge[M<<1]; 20 void ins(int u,int v,int wp,int wd) 21 { 22 edge[++sumedge]=Edge(u,v,head[u],wp,wd); 23 head[u]=sumedge; 24 } 25 26 queue<int>que; 27 int needp[N],needt[N],inq[N]; 28 void SPFA() 29 { 30 for(int i=1;i<=n;i++) 31 needp[i]=needt[i]=INF; 32 que.push(s);inq[s]=1; 33 needp[s]=0;needt[s]=0; 34 while(!que.empty()) 35 { 36 u=que.front(); 37 que.pop(); 38 inq[u]=0; 39 for(int i=head[u];i;i=edge[i].nx) 40 { 41 v=edge[i].v; 42 if(needt[v]>needt[u]+edge[i].wd&&needp[u]+edge[i].wp<=tps) 43 { 44 needt[v]=needt[u]+edge[i].wd; 45 needp[v]=needp[u]+edge[i].wp; 46 if(!inq[v]) 47 que.push(v),inq[v]=1; 48 } 49 } 50 } 51 } 52 53 int main() 54 { 55 scanf("%d%d",&n,&m); 56 for(int i=1;i<=m;i++) 57 { 58 scanf("%d%d%d%d",&u,&v,&ups,&dis); 59 ins(u,v,ups,dis);ins(v,u,ups,dis); 60 } 61 scanf("%d%d%d",&s,&t,&tps); 62 SPFA(); 63 if(needp[t]==INF) printf("-1"); 64 else printf("%d",needt[t]); 65 return 0; 66 }
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。