【C++】ZZ1761-维修道路 解题精讲
【Horn Coding Studio】CPP编程专栏(狄克斯特拉-算法)
题目
题目描述
从前,在一个王国中,在nn个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连。在经过一次严重的战争之后,有dd条道路被破坏了。国王想要修复国家的道路系统,现在有两个重要城市A和B之间的交通中断,国王希望尽快的恢复两个城市之间的连接。你的任务就是修复一些道路使AA与BB之间的连接恢复,并要求修复的道路长度最小。
输入
输入文件第一行为一个整数 n(2<n≤100)n(2<n≤100),表示城市的个数。这些城市编号从1到 nn 。
第二行为一个整数 mm ( n−1≤m≤12n(n−1))n−1≤m≤12n(n−1)), 表示道路的数目。
接下来的 mm 行,每行 3 个整数 i,j,k(1≤i,j≤n,i≠j,0<k≤100)i,j,k(1≤i,j≤n,i≠j,0<k≤100), 表示城市 ii 与 jj 之间有一条长 为 kk 的道路相连。
接下来一行为一个整数 d(1≤d≤m)d(1≤d≤m), 表示战后被破坏的道路的数目。在接下来的 dd 行中,每行两个整 数 ii 和 jj, 表示城市 ii 与 jj 之间直接相连的道路被破坏。
最后一行为两个整数A和B,代表需要恢复交通的两个重要城市。
第二行为一个整数 mm ( n−1≤m≤12n(n−1))n−1≤m≤12n(n−1)), 表示道路的数目。
接下来的 mm 行,每行 3 个整数 i,j,k(1≤i,j≤n,i≠j,0<k≤100)i,j,k(1≤i,j≤n,i≠j,0<k≤100), 表示城市 ii 与 jj 之间有一条长 为 kk 的道路相连。
接下来一行为一个整数 d(1≤d≤m)d(1≤d≤m), 表示战后被破坏的道路的数目。在接下来的 dd 行中,每行两个整 数 ii 和 jj, 表示城市 ii 与 jj 之间直接相连的道路被破坏。
最后一行为两个整数A和B,代表需要恢复交通的两个重要城市。
输出
输出文件仅一个整数,表示恢复 AA 与 BB 间的交通需要修复的道路总长度的最小值。
样例输入
3
2
1 2 1
2 3 2
1
1 2
1 3
样例输出
1
知识点普及
无。
一点即通
弗洛伊德的方法
先将有路的点都连接起来
由于只需要修改损坏的点
所以完好的道路是可以走的而且不需要修复
所以消耗为0
可以把损坏的边标记一下
把没被标记的也就是完好的边改为0
因为不需要消耗
最后再跑一遍弗洛伊德就好了
为是无向图,改路径值时一定要注意两边都要改变!!!!!! 别问我怎么知道的(爆零)
代码
本次代码
ZZOJ 100%AC,11099KB空间复杂度,11MS优秀时间复杂度。
Luogu OJ 50%TLE,6500KB时间复杂度,5MS超时
1 #include <bits/stdc++.h> 2 using namespace std; 3 int ap[1005][1005],dp[1005][1005]; 4 int n,m,x,y,k; 5 int d; 6 int a,b; 7 int main() { 8 memset(dp,0x3f,sizeof(dp)); 9 cin>>n>>m; 10 for(int i=1;i<=m;i++){ 11 cin>>x>>y>>k; 12 ap[x][y]=ap[y][x]=k; 13 dp[x][y]=dp[y][x]=0; 14 }cin>>d; 15 for(int i=1;i<=d;i++){ 16 cin>>x>>y; 17 dp[x][y]=dp[y][x]=ap[x][y]; 18 }for(int k=1;k<=n;k++){ 19 for(int i=1;i<=n;i++){ 20 for(int j=1;j<=n;j++){ 21 if(dp[i][j]>dp[i][k]+dp[k][j]){ 22 dp[i][j]=dp[i][k]+dp[k][j]; 23 } 24 } 25 } 26 }cin>>a>>b; 27 cout<<dp[a][b]; 28 return 0; 29 } 30 /************************************************************** 31 User: FZK 32 Language: C++ 33 Result: 正确 34 Time:11 ms 35 Memory:10068 kb 36 ****************************************************************/