D - 小Y上学记——要迟到了!
D?-?小Y上學記——要遲到了!
Time Limit:?2000/1000MS (Java/Others)????Memory Limit:?128000/64000KB (Java/Others)Problem Description
“你是我心中最美的云彩....",這不是大媽的廣場舞,而是小Y的鬧鐘,然而小Y由于昨晚玩得太瘋,導致今天居然沒被這鈴聲鬧醒!
當小Y睡眼惺忪地醒來后,發現距離第一節上課還有不到5分鐘了!
小Y心想,跑過去教室肯定來不及了,只好發動一下超能力。
小Y的超能力是可以瞬間通過一條路,也就是說從一頭瞬間移動到另一頭,然而由于某種原因,小Y最多只能發動K次,不然就會被大家發現,就會被上交給國家。
那么小Y想問你最快要多長時間到達教室?
Input
多組數據,每組數據首先是三個整數N,M,K,表示校園道路的節點數,校園道路數,還有小Y能發動超能力的最大次數。
(2<=N<=1000,N-1<=M<=10000,0<=K<=10)
接下來是M行,每行是三個數字u,v,w,表示在節點u和節點v中有一條需要小Y跑w分鐘的路,道路都是沒有方向限制的。
(1<=u,v<=N,0<w<=1000)
可能有自環以及重邊
其中小Y宿舍在1號節點,教室在n號節點。
保證從宿舍到教室至少存在一條路。
Output
對于每組數據,輸出一個整數,表示小Y在超能力的幫助下最少要多少時間到達教室。Sample Input
4 4 0 1 2 2 2 4 3 1 3 1 3 4 4 4 4 1 1 2 2 2 4 3 1 3 1 3 4 4Sample Output
5 1Hint
對于第一組數據,由于小Y不能使用超能力,無論是1-2-4還是1-3-4,都需要花費小Y5分鐘的時間
對于第二組數據,由于小Y可以用一次超能力,因此可以選擇1-3-4這條道路,其中3-4這條道路使用超能力通過。只需要1分鐘。
解法:
要使得所用時間最少,當然是盡可能的使用全部次數的超能力,把平面二維的圖,弄成立體三維的,一共有K+1層,表示有K次超能力。則把每兩層之間的連接的邊權看作為0,然后用廣度搜索的方法以及SPFA的思想,去求這個三維圖的最短路徑,起始點為Dis[0][1],終點為Dis[K][N]。注意要判斷重邊,環,以及數組,鄰接表要開足夠大、
1 #include<stdio.h> 2 #include<string.h> 3 #define INF 99999999 4 #define MAX 1016 5 using namespace std; 6 int Dis[15][MAX];/*Dis[i][j]記錄到達第i層的點j的最短路*/ 7 int Sign[100810];/*隊列*/ 8 int D_ID[100810];/*記錄隊列元素所對的層數*/ 9 int First[MAX]; /*鄰接表頭*/ 10 struct edge{int TO,Next,Vlaue;}ID[MAX*20];/*鄰接表*/ 11 int SIGN;/*邊編號,從1開始*/ 12 13 void Add_E(int x,int y,int z) /*添加邊*/ 14 { 15 ID[SIGN].TO=y; 16 ID[SIGN].Vlaue=z; 17 ID[SIGN].Next=First[x]; 18 First[x]=SIGN++; 19 } 20 void Cread(int N,int K)/*初始化*/ 21 { 22 int i,j; 23 for(i=0;i<=K;i++) 24 { 25 for(j=1;j<=N;j++) 26 {First[j]=0;Dis[i][j]=INF;} 27 } 28 } 29 void Jude(int x,int y,int c)/*判斷重邊,添加點*/ 30 { 31 int i; 32 int TMD=1; 33 for(i=First[x];i!=0;i=ID[i].Next) 34 { 35 if(ID[i].TO==y) 36 { 37 TMD=0; 38 if(ID[i].Vlaue>c) 39 {ID[i].Vlaue=c;TMD=2;break;} 40 } 41 } 42 if(TMD==2) 43 { 44 for(i=First[y];i!=0;i=ID[i].Next) 45 { 46 if(ID[i].TO==x) 47 { 48 if(ID[i].Vlaue>c) 49 {ID[i].Vlaue=c;break;} 50 } 51 } 52 return ; 53 } 54 if(TMD==1) 55 { 56 Add_E(x,y,c);/*無線圖,所以需要左右兩邊*/ 57 Add_E(y,x,c);/*無線圖,所以需要左右兩邊*/ 58 } 59 return ; 60 } 61 void SPFA(int s,int m,int K) 62 { 63 int i,j,k,Start=0,End=1,D=0; 64 int Visit[15][MAX]; 65 Sign[Start] = s; 66 D_ID[Start]=0; 67 Dis[D][s] = 0; 68 while(Start<End) 69 { 70 D=D_ID[Start];/*獲取隊頭元素的層數*/ 71 k=Sign[Start++];/*獲取隊頭元素(點)*/ 72 Visit[D][k]=0; 73 for(i=First[k];i!=0;i=ID[i].Next)/*更新第D層的最短路*/ 74 { /*更新第D層的最短路*/ 75 if(ID[i].Vlaue>0&&Dis[D][ID[i].TO]>ID[i].Vlaue+Dis[D][k]) 76 { 77 Dis[D][ID[i].TO]=Dis[D][k]+ID[i].Vlaue; 78 if(!Visit[D][ID[i].TO]) 79 { 80 D_ID[End]=D;/*記錄入隊元素的層數*/ 81 Sign[End++]=ID[i].TO; 82 Visit[D][ID[i].TO]=1; 83 } 84 } 85 } 86 for(i=First[k],D=D+1;i!=0&&D<=K;i=ID[i].Next) 87 { /*更新第D+1層的最短路*/ 88 if(ID[i].Vlaue>0&&Dis[D][ID[i].TO]>Dis[D-1][k]) 89 { 90 Dis[D][ID[i].TO]=Dis[D-1][k]; 91 if(!Visit[D][ID[i].TO]) 92 { 93 D_ID[End]=D; 94 Sign[End++]=ID[i].TO; 95 Visit[D][ID[i].TO]=1; 96 } 97 } 98 } 99 } 100 return ; 101 } 102 int main() 103 { 104 int i,j,T,N,a,b,c,K; 105 while(scanf("%d%d%d",&N,&T,&K)!=EOF) 106 { 107 Cread(N,K);SIGN=1; 108 for(i=0;i<T;i++) 109 { 110 scanf("%d%d%d",&a,&b,&c); 111 Jude(a,b,c); 112 } 113 SPFA(1,N,K); 114 printf("%d\n",Dis[K][N]); 115 } 116 return 0; 117 } View Code
?
轉載于:https://www.cnblogs.com/Wurq/p/4702420.html
總結
以上是生活随笔為你收集整理的D - 小Y上学记——要迟到了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 代码
- 下一篇: 1071. Speech Pattern