zoukankan      html  css  js  c++  java
  • 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


     

  • 相关阅读:
    iSCSI又称为IPSAN
    文档类型定义DTD
    HDU 2971 Tower
    HDU 1588 Gauss Fibonacci
    URAL 1005 Stone Pile
    URAL 1003 Parity
    URAL 1002 Phone Numbers
    URAL 1007 Code Words
    HDU 3306 Another kind of Fibonacci
    FZU 1683 纪念SlingShot
  • 原文地址:https://www.cnblogs.com/Wurq/p/4702420.html
Copyright © 2011-2022 走看看