zoukankan      html  css  js  c++  java
  • CODEVS 1817 灾后重建 Label:Floyd || 最短瓶颈路

    描述

    灾后重建(rebuild) 
      B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响。但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车。换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄。 
      给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的。并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车。若t[i]为0则说明地震未对此地区造成损坏,一开始就可以通车。之后有Q个询问(x, y, t),对于每个询问你要回答在第t天,从村庄x到村庄y的最短路径长度为多少。如果无法找到从x村庄到y村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄y在第t天仍未重建完成 ,则需要返回-1。 

    输入格式

      输入文件rebuild.in的第一行包含两个正整数N,M,表示了村庄的数目与公路的长度。 
      第二行包含N个非负整数t[0], t[1], …, t[N – 1],表示了每个村庄重建完成的时间,数据保证了t[0] ≤ t[1] ≤ … ≤ t[N – 1]。 
      接下来M行,每行3个非负整数i, j, w,w为不超过10000的正整数,表示了有一条连接村庄i与村庄j的道路,长度为w,保证i≠j,且对于任意一对村庄只会存在一条道路。 
      接下来一行也就是M+3行包含一个正整数Q,表示Q个询问。 
      接下来Q行,每行3个非负整数x, y, t,询问在第t天,从村庄x到村庄y的最短路径长度为多少,数据保证了t是不下降的。 

    输出格式

      输出文件rebuild.out包含Q行,对每一个询问(x, y, t)输出对应的答案,即在第t天,从村庄x到村庄y的最短路径长度为多少。如果在第t天无法找到从x村庄到y村庄的路径,经过若干个已重建完成的村庄,或者村庄x或村庄y在第t天仍未修复完成,则输出-1。 

    测试样例1

    输入

    4 5 
    1 2 3 4 
    0 2 1 
    2 3 1 
    3 1 2 
    2 1 4 
    0 3 5 

    2 0 2 
    0 1 2 
    0 1 3 
    0 1 4 

    输出

    -1 
    -1 

    备注

    【数据规模】 
      对于30%的数据,有N≤50; 
      对于30%的数据,有t[i] = 0,其中有20%的数据有t[i] = 0且N>50; 
      对于50%的数据,有Q≤100; 
      对于100%的数据,有N≤200,M≤N*(N-1)/2,Q≤50000,所有输入数据涉及整数均不超过100000。 

    代码

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int n,m,point=0;
     8 int T[505],g[505][505],note[505];//下标从0开始 
     9 
    10 void init_(){
    11     memset(g,-1,sizeof(g));
    12     scanf("%d%d",&n,&m);
    13     
    14     for(int i=0;i<n;i++){
    15         scanf("%d",&T[i]);
    16         if(T[i]==0) note[i]=1,point=i;
    17     }
    18     for(int i=1;i<=m;i++){
    19         int x,y,w;
    20         scanf("%d%d%d",&x,&y,&w);
    21         g[x][y]=w;
    22         g[y][x]=w;
    23     }
    24 }
    25 
    26 void floyd(int x){
    27     point=x+1,note[x]=1;
    28 
    29     for(int i=0;i<n;i++){//更新到x的距离
    30         for(int j=0;j<n;j++){
    31             if(note[i] && note[j] && g[i][j]!=-1 && g[j][x]!=-1){
    32                 if(g[i][j]+g[j][x]<g[i][x] || g[i][x]==-1){
    33                     g[x][i]=g[i][x]=g[i][j]+g[j][x];
    34                 }        
    35             }
    36         }
    37     }
    38     
    39     for(int i=0;i<n;i++){//更新以x为中继的点
    40         for(int j=0;j<n;j++){
    41             if(note[i] && note[j] && g[i][x]!=-1 && g[x][j]!=-1){
    42                 if(g[i][x]+g[x][j]<g[i][j] || g[i][j]==-1){
    43                     g[i][j]=g[i][x]+g[x][j];
    44                 }
    45             }
    46         }
    47     }
    48 }
    49 
    50 
    51 void solve(){
    52     int x,y,t,ask;
    53     scanf("%d",&ask);
    54     
    55     if(point!=0){//对T[i]=0的点先进行最短路
    56         for(int k=0;k<=point;k++)
    57             for(int i=0;i<=point;i++)
    58                 for(int j=0;j<=point;j++)
    59                     if(g[i][k]!=-1 && g[k][j]!=-1)
    60                         if(g[i][k]+g[k][j]<g[i][j] || g[i][j]==-1)
    61                             g[i][j]=g[i][k]+g[k][j];
    62     }
    63     
    64     while(ask--){
    65         scanf("%d%d%d",&x,&y,&t);
    66         while(t>=T[point] && point<n) floyd(point);
    67         if( note[x] && note[y] ) printf("%d
    ",g[x][y]);
    68         else puts("-1");
    69     }
    70 }
    71 
    72 int main(){
    73 //  freopen("01.in","r",stdin);
    74     init_();
    75     solve();
    76     return 0;
    77 }

    不知道为什么洛谷过不了,TYVJ 和 CODEVS 都可以过

    当然可以在线floyd,O(n^4),可以过4个点(我是不会说我之前就是这么做的)

    转个题解:

    数据规模比较小,所以用矩阵+离线floyd(在线spfa貌似要超时)

    floyd算法中枚举的k是中转点,在这道题中就可以按时间顺序把点当作中转点,挨个儿加入图中,并且同时将‘时间恰当的询问’求出来(是指询问的时间<=t[k]的询问)

    ﹡注意题中所给的数据已经排好了序

    最小瓶颈路:

    题目大意:有一些村庄与它们之间的通路(即是图中的顶点和边),每条通路都有一个修复时间,要求何时所有村庄都可以连通。

    其实就是一个无向带权图,要求最小瓶颈生成树(这棵树的边的最大值为这棵树的值)。可以用prim算法与kruskal算法。也可以用dijkstra算法。

    为什么可以用dijkstra算法?首先,所有边权值非负。然后可以发现,当两个村庄相通时,它们的最短路(指的是瓶颈最短路)即为它们相通的最短时间,因为它们相通的条件是存在某几条修好的公路将它们连接,于是时间就取决于这几条公路中最迟建好的那条,于是把时间看成权,任意取一个顶点,使用DJ算法,求得他到其他所有公路的最短瓶颈路(最短时间内两村庄通车),因为是无向图,所以A到B的最短路即为B到A的最短路。于是源与其他所有顶点最短路的最大值即为所求。

    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!
  • 相关阅读:
    modesim仿真
    EP3C系列FPGA的JTAG检测不了,JTAG下载失败,AS可以下载,下载完成后不执行程序
    本机修改虚拟机linux中的代码文件
    linux中的diff命令
    php中的elseif和else if
    php将数据写入另外一个文件
    IE6下的png不透明问题
    cookie的封装
    php从接口获取数据转成可以用的数组或其他(含转换编码)
    如何让后加载的元素被一开始就有的css样式渲染成功(强制提升css优先级)
  • 原文地址:https://www.cnblogs.com/radiumlrb/p/5858676.html
Copyright © 2011-2022 走看看