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 

4

备注

【数据规模】 
  对于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\n",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的最短路。于是源与其他所有顶点最短路的最大值即为所求。

时间: 2024-12-06 09:37:34

CODEVS 1817 灾后重建 Label:Floyd || 最短瓶颈路的相关文章

codevs 1817 灾后重建

/* 暴力暴力 离线每次添边 堆优化dij 70 SPFA 80..... */ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #include<vector> #define maxn 210 using namespace std; int n,m,Q,num,head[maxn],dis[maxn

【题解】灾后重建——(floyd)

这道题告诉我,背的掉板子并不能解决一切问题,理解思想才是关键,比如不看题解,我确实想不清楚这题是弗洛伊德求最短路 (我不该自不量力的说我会弗洛伊德了我错了做人果然要谦虚) 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向

洛谷P1119 灾后重建(floyd)

P1119 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的.并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车.若t[i]为0则说明地震未对此地区造成损坏,一

[Luogu P1119] 灾后重建 (floyd)

题面 传送门:https://www.luogu.org/problemnew/show/P1119 Solution 这题的思想很巧妙. 首先,我们可以考虑一下最暴力的做法,对每个时刻的所有点都求一遍单元最短路 因为最多只有200个时刻,时间复杂度为O(n^3log(n+m))) (堆优化的迪杰斯特拉) 显然对于n=200,并过不了 我们可有进一步分析 这一题,我们堆优化的迪杰斯特拉慢在每加入一个点,我们每一次都得对全图彻彻底底做一轮松弛 那换个角度考虑,如果我只松弛经过新加入的点的点对呢?

P1119 灾后重建

P1119 灾后重建 题目背景 B地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出B地区的村庄数N,村庄编号从0到N-1,和所有M条公路的长度,公路是双向的.并给出第i个村庄重建完成的时间t[i],你可以认为是同时开始重建并在第t[i]天重建完成,并且在当天即可通车.若t[i]为0则说明地震未对此地区造成损坏,一

灾后重建「解题报告」

P1119 灾后重建 Luogu P1119 题意 有n个村庄m条路,每个村庄都被地震摧毁,在某一时刻 \(t_i\)被修好.对于某条路,只有当它连接的两个村庄都被修好后才能通过.有q个询问,询问在某一时刻两村庄间的最短路. 第一行包含两个正整数 \(n,m\) . 第二行包含 \(n\) 个非负整数 \(t_0, t_1,-, t_{N-1}\),表示每个村庄重建完成的时间,数据保证了 \(t_0 ≤ t_1 ≤ - ≤ t_{N-1}\) 接下来 \(m\) 行,每行3个非负整数 \(i,j

AC日记——灾后重建 洛谷 P1119

灾后重建 思路: 看到n<=200,思考弗洛伊德算法: 如何floyed呢? floyed是一种动态规划求最短路的算法: 它通过枚举中间点来更新两点之间最短路: 回到这个题本身: 所有点的重建完成的时间和询问的时间都已经排好序了: 所以,我们把floyed拆开: 对于一个三维的k,i,j的floyed算法: 我们判断当前的询问在哪两个相邻的k之间: 然后,我们判断当时的连通性以及最短路情况: 来,上代码: #include <cstdio> #include <cstring>

P1119 灾后重建 floyd

题目背景 BB地区在地震过后,所有村庄都造成了一定的损毁,而这场地震却没对公路造成什么影响.但是在村庄重建好之前,所有与未重建完成的村庄的公路均无法通车.换句话说,只有连接着两个重建完成的村庄的公路才能通车,只能到达重建完成的村庄. 题目描述 给出BB地区的村庄数NN,村庄编号从00到N-1N−1,和所有MM条公路的长度,公路是双向的.并给出第ii个村庄重建完成的时间t_iti?,你可以认为是同时开始重建并在第t_iti?天重建完成,并且在当天即可通车.若t_iti?为00则说明地震未对此地区造

灾后重建(对Floyd的认识)

传送门 主要考察了对Floyd算法的认识程度(告诉我们背板子是不行的). Floyd,代码很简单,而其本质思想是通过其他的点进行中转来求的两点之间的最短路.因为我们知道,两点之间有多条路,如果换一条路可以缩短距离的话,就更新最短距离.而它最本质的思想,就是用其他的点进行中转,从而达到求出最短路的目的.(精辟总结摘自洛谷题解). 对于这道题,要求得任意两点间的最短路,但是可以用来做中转点的点确实不定的. 我们可以对于每次因时间增加而加入的新的可以做中转点的点,运用Floyd的本质解题. 题目保证t