D

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 4

Sample Output

5
1

Hint

对于第一组数据,由于小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
",Dis[K][N]);
115     }
116     return 0;
117 }
View Code


 

原文地址:https://www.cnblogs.com/Wurq/p/4702420.html