1 条题解
-
0
自动搬运
来自洛谷,原作者为

zjy111
**搬运于
2025-08-24 21:39:04,当前版本为作者最后更新于2019-07-30 09:13:22,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
这是绿名蒟蒻第二次发题解(第一次没有通过)......
一道相对简单的省选题(最短路模板题)
也是我AC的第一道绿题每两个城市之间的时间由地形和有无魔法石决定,而每个地形通过的时间是固定的(2,6,4,8,6,10,14),输入了魔法石的有无,所以时间就出来了。
众所周知,最短路算法很多,这里我选用了Floyd算法(时复N^3),我觉得比较好懂,代码也简单(城市编号不超过100,这不是明显暗示用Floyd吗)
反正我连Dijkstra都不会以下是Floyd具体思路:
用dis[i][j]数组表示i~j的最短路径,从1~n枚举中间点k,如果从i到j过k有更短的路径就刷新,否则保留原来路径(有点动规思想,转移方程:dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]))
注意事项: 1 循环时要把中间点k放在最外层; 2 一开始时(输入前)每两个点之间都是没有路的,所以距离要标成无限而不是0,否则会导致所有点之间的距离都是0 3 这种算法只适用于无负环图(也就是不存在边权值和<0的环)
不过好像和这题没有关系献上码风奇特的代码(有一些注释,不过我语文不太好,还请见谅)
#include <bits/stdc++.h> using namespace std; unsigned long long i,j,k,x,y,c,dist[105][105];//这个数组记录距离 int s[8]={99999,2,6,4,8,6,10,14};//这个数组记录每个地形花费时间(我习惯从1开始,所以s[0]要空出) bool ck[8];//判断有没有石头 int main(){ memset(dis,100000,sizeof(dis));//初始化:必须足够大(即一开始最短路是无限长) for(i=1;i<8;i++)cin>>ck[i]; cin>>x>>y>>c;//x起点,y终点(我更习惯用变量i,j写for循环) if(x==y){ //特判:如果x,y相等就是0!!!!(第一次提交WA了9号点,就因为这个) cout<<0; return 0; } while(c--){ cin>>i>>j>>k; if(ck[k]){ //有石头,花费减半 dis[i][j]=s[k]/2; dis[j][i]=s[k]/2;//注意这里是双向边,所以两头都要记录 } else { //没石头,花费照常 dis[i][j]=s[k]; dis[j][i]=s[k]; } } for(k=1;k<=100;k++){ //Floyd核心代码,具体思路见上(注意中间点循环放最外层) for(i=1;i<=100;i++){ for(j=1;j<=100;j++){ dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } } } cout<<dis[x][y]<<endl;//最后输出从x到y最短路距离 return 0; }
- 1
信息
- ID
- 1600
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者