https://www.luogu.com.cn/problem/P6464?contestId=180677
传智专修学院里有
n 栋教学楼,有 m 条双向通行道路连接这些教学楼,不存在重边和自环。每条道路都有一定的长度,而且所有教学楼之间都可以直接或者间接的通过道路到达。我们可以很容易的求出这些教学楼之间的最短路。
为了使交通更为顺畅,校方决定在两个教学楼里增设一对传送门。传送门可以将这对教学楼的距离直接缩短为 0。利用传送门,某些教学楼之间的最短路的距离就变短了。
由于预算有限,学校里只能安装一对传送门。但是校长希望尽可能方便学生,使任意两点之间的最短路长度的总和最小。当然啦,从 x 教学楼到 y 教学楼的长度和从 y 教学楼到 x 教学楼的长度只需要统计一次就可以了。
上述便是题目,简单来说就是学院有n个教学楼,教学楼上一共有m条通道这些通道可以互通,但是有一个传送门可以直接将这一栋的人传送到另一栋上面,传送的权值为0,求出有有传送门的情况下去完每栋楼最少要走的路是多少
由题意可知上述题目是使用floyd算法和枚举法来解决书取得该多元的最小值,我们假定一个坐标,我们在一号楼然后我们把传送门放在二号楼来算出此时的最短路,再将传送门放在三号楼算出最短路等一号楼的这种情况算完了我们再从二号楼开始
以此类推得出结论
点击查看代码
`#include<bits/stdc++.h>
using namespace std;
int to[100000],mp[5000][5000] //建立变量来进行存储;
int main() {
int n, m, a, b, c;
cin >> n >> m;
for(int i = 1; i<= n; i++) {
for(int j = 1; j<= n; j++) {
if(i==j)mp[i][j]=0;
else mp[i][j]=1e8//进行初始化这样子才能使得接下来的想法中找到最小值;
//否则默认mp为0会导致结果出现错误
}
}
for(int i = 1; i <= m; i++) {
cin >> a >> b >> c;
if(mp[a][b] > c) {
mp[a][b]=c;
mp[b][a]=c;//因为是双向边所以都要进行记录
}
}
for(int k = 1; k <= n; k++) {
for(int i = 1; i<= n; i++) {
for(int j = 1; j <= n; j++) {
mp[i][j]=min(mp[i][j],mp[k][j]+mp[i][k]);//这个地方为正常的floyd算法题目所用的比这个稍微复杂一些
}
}
}
long long t = 0,ans=INT_MAX;
for(int men=1; men<n;men++) {//传送门所在的楼是哪栋
for(int k = men+1; k <= n; k++) {//为什么要加一,假设men=k传送门无意义但这样子可以稍微减少时间复杂度
t=0;
for(int i = 1; i< n; i++) {//开始遍历起点到哪个终点的路径
for(int j = i+1; j <= n; j++) {
if(men!=i||j!=k)//出发点等于传送门的位置和跳跃点等于直接到的地方这样子无意义.
t+=min(mp[i][j],min(mp[men][j]+mp[k][i],mp[men][i]+mp[k][j]));//开始比较将起点到跳跃点,跳跃点从传送门传过去和起点到传送门,传送门再到跳跃点的值再到我要的终点进行比较选出权值
//小的那一个并比较和直接过去的权值比
}
}
ans=min(ans,t);//选出权值最小的那一个进行比较与记录
}
}
cout <<ans<< endl;
return 0;
}`