九度oj 题目1447:最短路
- 题目描述:
-
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
- 输入:
-
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。输入保证至少存在1条商店到赛场的路线。
当输入为两个0时,输入结束。
- 输出:
-
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间。
- 样例输入:
-
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
- 样例输出:
-
3
2
本来是一道很简单的迪杰特斯拉算法,一开始提交的代码如下#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#define MAX 103
#define inf 0x3f3f3f3f
int map[MAX][MAX];
bool flag[MAX]; int main(int argc, char const *argv[])
{
int n, m;
scanf("%d %d",&n,&m);
while(n != || m != ) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
map[i][j] = inf;
flag[i] = false;
}
} int a,b,c;
for(int i = ; i < m; i++) {
scanf("%d %d %d",&a,&b,&c);
map[a][b] = c;
map[b][a] = c;
} flag[] = true;
int count = ;
while(count <= n) {
int min = MAX;
int mini = -;
for(int i = ; i <= n; i++) {
if(flag == false) {
if(map[][i] < min) {
min = map[][i];
mini = i;
}
}
}
map[][mini] = min;
flag[mini] = true;
for(int i = ; i <= n; i++) {
int dis = map[][mini] + map[mini][i];
if(dis < map[][i]) {
map[][i] = dis;
}
}
count++;
}
printf("%d\n",map[][n]);
scanf("%d %d",&n,&m);
}
return ;
}一开始百思不得其解究竟哪里做错了,只好先换一种写法
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#define MAX 103
#define inf 999999999
int map[MAX][MAX];
bool flag[MAX];
int lowCost[MAX]; int main(int argc, char const *argv[])
{
int n, m;
scanf("%d %d",&n,&m);
while(n != || m != ) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
map[i][j] = inf;
}
flag[i] = false;
} int a,b,c;
for(int i = ; i < m; i++) {
scanf("%d %d %d",&a,&b,&c);
map[a][b] = c;
map[b][a] = c;
} flag[] = true;
for(int i = ; i <= n; i++) {
lowCost[i] = map[][i];
} for(int i = ; i <= n; i++) {
int min = inf;
int v = -;
for(int j = ; j <= n; j++) {
if(flag[j] == false && lowCost[j] < min) {
min = lowCost[j];
v = j;
}
}
flag[v] = true; for(int j = ; j <= n; j++) {
if(flag[j] == false && lowCost[v]+map[v][j] < lowCost[j]) {
lowCost[j] = lowCost[v]+map[v][j];
}
}
} printf("%d\n",lowCost[n]);
scanf("%d %d",&n,&m);
}
return ;
}后来经仔细排查,第一种写法的错误有两处,一是33行,min = inf
二是36行flag[i] ==false
另一种办法是使用Floyd算法,但开始我的代码是这样的
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#define MAX 103
#define inf 999999999
int map[MAX][MAX]; int main(int argc, char const *argv[])
{
int n, m;
scanf("%d %d",&n,&m);
while(n != || m != ) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
map[i][j] = inf;
}
} for (int i=; i<=n; ++i)
map[i][i] = ; int a,b,c;
for(int i = ; i < m; i++) {
scanf("%d %d %d",&a,&b,&c);
map[a][b] = c;
map[b][a] = c;
} for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
for(int k = ; k <= n; k++) {
if (map[i][k] == inf || map[k][j] == inf)
continue;
if(map[i][k]+map[k][j] < map[i][j]) {
map[i][j] = map[i][k] + map[k][j];
}
}
}
}
printf("%d\n",map[][n]);
scanf("%d %d",&n,&m);
}
return ;
}但WA了,而真正的算法是这样的
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#define MAX 103
#define inf 999999999
int map[MAX][MAX]; int main(int argc, char const *argv[])
{
int n, m;
scanf("%d %d",&n,&m);
while(n != || m != ) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
map[i][j] = inf;
}
} int a,b,c;
for(int i = ; i < m; i++) {
scanf("%d %d %d",&a,&b,&c);
map[a][b] = c;
map[b][a] = c;
} for(int k = ; k <= n; k++) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
if (map[i][k] == inf || map[k][j] == inf)
continue;
if(i != j && map[i][k] + map[k][j] < map[i][j]) {
map[i][j] = map[i][k] + map[k][j];
}
}
}
}
printf("%d\n",map[][n]);
scanf("%d %d",&n,&m);
}
return ;
}注意算法是 先对中间点进行遍历,不断增加新的中间点以得到更优的答案
九度oj 题目1447:最短路的更多相关文章
- 九度OJ 题目1384:二维数组中的查找
/********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...
- hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人
钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- 九度oj题目&吉大考研11年机试题全解
九度oj题目(吉大考研11年机试题全解) 吉大考研机试2011年题目: 题目一(jobdu1105:字符串的反码). http://ac.jobdu.com/problem.php?pid=11 ...
- 九度oj 题目1007:奥运排序问题
九度oj 题目1007:奥运排序问题 恢复 题目描述: 按要求,给国家进行排名. 输入: 有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号 ...
- 九度oj 题目1087:约数的个数
题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...
- 九度OJ题目1105:字符串的反码
tips:scanf,cin输入字符串遇到空格就停止,所以想输入一行字符并保留最后的"\0"还是用gets()函数比较好,九度OJ真操蛋,true?没有这个关键字,还是用1吧,还是 ...
- 九度oj题目1009:二叉搜索树
题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...
- 九度oj题目1002:Grading
//不是说C语言就是C++的子集么,为毛printf在九度OJ上不能通过编译,abs还不支持参数为整型的abs()重载 //C++比较正确的做法是#include<cmath.h>,cou ...
- 九度OJ题目1003:A+B
while(cin>>str1>>str2)就行了,多简单,不得不吐槽,九度的OJ真奇葩 题目描述: 给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号", ...
随机推荐
- [转]Java 8 Optional类深度解析(null处理)
原文链接:http://www.importnew.com/6675.html 本文由 ImportNew - 高俊阳 翻译自 javacodegeeks.欢迎加入翻译小组.转载请见文末要求. 身为一 ...
- ios,弹窗遮罩滚动穿透解决方案
- python部分 + 数据库 + 网络编程
PS:附上我的博客地址,答案中略的部分我的博客都有,直接原标题搜索即可.https://www.cnblogs.com/Roc-Atlantis/ 第一部分 Python基础篇(80题) 为什么学习P ...
- 日常博客-png,jpeg,gif图片
个人博客记录:2017-11-09 png-----32位无损压缩算法形成的图片,主要用于logo小图标和一些点缀的小图像.放大缩小不会失真,质量好 jpeg,jpg-----压缩比例较高(可达到10 ...
- UIView动画效果之----翻转.旋转.偏移.翻页.缩放.取反的动画效
翻转的动画 //开始动画 [UIView beginAnimations:@"doflip" context:nil]; //设置时常 [UIView setAnimationDu ...
- spring 上传附件
jsp: <form class='uk-form' action="savelead" method="post" enctype="mult ...
- (十四)maven之启动tomcat
前言:在网上找了好几种方法启动web项目.比较好用的是:①在Project Facets勾上Dynamic....,但是这个方法会改变项目结构(把WebContent的东西都弄出来了):②使用jett ...
- 如何用JavaScript判断前端应用运行环境(移动平台还是桌面环境)
我们部署在某些云平台或者Web服务器上的前端应用,既可以用PC端浏览器访问,也可以用手机上的浏览器访问. 在前端应用里,有时候我们需要根据运行环境的不同做出对应处理.比如下面这段逻辑,如果判断出应用当 ...
- JavaScript中对象的属性:如何遍历属性
for/in 语句循环遍历对象的属性. js中获取key得到某对象中相对应的value的方法:obj.key js中根据动态key得到某对象中相对应的value的方法有二: 一.var key = & ...
- 标注偏置问题(Label Bias Problem)和HMM、MEMM、CRF模型比较<转>
转自http://blog.csdn.net/lskyne/article/details/8669301 路径1-1-1-1的概率:0.4*0.45*0.5=0.09 路径2-2-2-2的概率:0. ...