• 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


     

  • 相关阅读:
    词义辨析:事件与事故
    术语-BPM:BPM
    职位:DBA
    职业-软件:软件测试工程师
    职位-软件工程师:软件工程师
    职业-IT:全栈工程师
    术语-技术栈:技术栈
    .NET Core:目录
    .NET Core:.Net Core 百科
    术语-抽象:抽象
  • 原文地址:https://www.cnblogs.com/Wurq/p/4702420.html
Copyright © 2020-2023  润新知