POJ 1797
2016-03-14 16:34
239 查看
题目咋一看,就是 最短路问题,解法是 Dijkstra 算法的变体。
题目大意是 给定n个城市,和 它们之间的 m 条街道,以及街道上的 最大载重。 可以这样理解,现在找一辆车从 城市 1 到往 城市 n,求最大的载重,前提是 不能把 街道压坏,也就是载重必须小于等于 给定的街道最大载重。
这里只需要 将 Dijkstra 算法里面的 更新边的条件 改一下,也就是 d[i] 表示1城市到 i 城市 可以承受的最大载重,先找到 d[] 的最大值,然后根据 是否min(d[k],map[k][j]) 大于 d[j],来更新 d[] 数组。
#include <iostream>
using namespace std;
//#define min(a,b) ((a)<(b)?(a):(b))
#define min(a,b) (a<b?a:b)
#define MAXN 1010
int map[MAXN][MAXN];
bool vis[MAXN];
int d[MAXN];
int n; //表示n个城市
int dijkstra(){
int i,j,k,temp;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
d[i] = map[1][i];
for(i=1;i<=n;i++){
temp = -1;
k = 0;
for(j=1;j<=n;j++){
if(!vis[j]&&d[j]>temp){
temp = d[j];
k = j;
}
}
vis[k] = 1;
for(j=1;j<=n;j++){
if(!vis[j]&&d[j]<min(d[k],map[k][j])){
d[j] = min(d[k],map[k][j]);
}
}
}
return d
;
}
int main(){
int plans;
cin>>plans;
int m,i,j;
int v1,v2,v3;
int index = 1;
while(plans--){
cin>>n>>m;
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
map[i][j] = 0;
for(i=1;i<=m;i++){
cin>>v1>>v2>>v3;
map[v1][v2] = map[v2][v1] = v3;
}
cout<<"Scenario #"<<index++<<":"<<endl;
cout<<dijkstra()<<endl;
cout<<endl;
}
return 0;
}
这里有几点要注意: 可能是我 比较粗心。。
首先,index的值,每次output之后 都要自增;第二,每次output之后,都要换行(题目中有写)。。
第三,在 Dijkstra 算法里面,求d[] 最大值时,注意不能在初始状态把 temp = d[1], k = 1,这样写的话,会导致后面 相同值的标号 无法计算到,若d[1] = d[2],那么 k 就永远等于2了。
第四,也是最重要的 一点,那就是 预定义函数了,这个调试了 我好久。
#define min(a,b) ((a)<(b)?(a):(b)) 或者写成 #define min(a,b) (a<b?a:b) , 对于这道题 都可以。
不过我还是建议 用前一种,比较保险,因为用 define 预定义函数,必须要将 参数 都加括号。
至于为什么,我举一个经典的例子:
#define function(a) a*a
调用的时候 function(2+2) 就会 出错,应该是16, 它输出8,这里把括号扩在外面都没用,要((a)*(a)),把参数作为一个整体。
我在做这道题的时候, 算法方面没什么问题,但是一些小的细节 困了我好久,每次调试 都 感觉好烦。但 渐渐的,我发现,只有自己亲手写代码,调试,发现错误,水平才会提高。照着别人代码写,很多问题 和 细节 都会 被略去。 所以,我建议,可以借鉴别人的思想,但 代码一定要自己敲,自己还原算法。
题目大意是 给定n个城市,和 它们之间的 m 条街道,以及街道上的 最大载重。 可以这样理解,现在找一辆车从 城市 1 到往 城市 n,求最大的载重,前提是 不能把 街道压坏,也就是载重必须小于等于 给定的街道最大载重。
这里只需要 将 Dijkstra 算法里面的 更新边的条件 改一下,也就是 d[i] 表示1城市到 i 城市 可以承受的最大载重,先找到 d[] 的最大值,然后根据 是否min(d[k],map[k][j]) 大于 d[j],来更新 d[] 数组。
#include <iostream>
using namespace std;
//#define min(a,b) ((a)<(b)?(a):(b))
#define min(a,b) (a<b?a:b)
#define MAXN 1010
int map[MAXN][MAXN];
bool vis[MAXN];
int d[MAXN];
int n; //表示n个城市
int dijkstra(){
int i,j,k,temp;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
d[i] = map[1][i];
for(i=1;i<=n;i++){
temp = -1;
k = 0;
for(j=1;j<=n;j++){
if(!vis[j]&&d[j]>temp){
temp = d[j];
k = j;
}
}
vis[k] = 1;
for(j=1;j<=n;j++){
if(!vis[j]&&d[j]<min(d[k],map[k][j])){
d[j] = min(d[k],map[k][j]);
}
}
}
return d
;
}
int main(){
int plans;
cin>>plans;
int m,i,j;
int v1,v2,v3;
int index = 1;
while(plans--){
cin>>n>>m;
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
map[i][j] = 0;
for(i=1;i<=m;i++){
cin>>v1>>v2>>v3;
map[v1][v2] = map[v2][v1] = v3;
}
cout<<"Scenario #"<<index++<<":"<<endl;
cout<<dijkstra()<<endl;
cout<<endl;
}
return 0;
}
这里有几点要注意: 可能是我 比较粗心。。
首先,index的值,每次output之后 都要自增;第二,每次output之后,都要换行(题目中有写)。。
第三,在 Dijkstra 算法里面,求d[] 最大值时,注意不能在初始状态把 temp = d[1], k = 1,这样写的话,会导致后面 相同值的标号 无法计算到,若d[1] = d[2],那么 k 就永远等于2了。
第四,也是最重要的 一点,那就是 预定义函数了,这个调试了 我好久。
#define min(a,b) ((a)<(b)?(a):(b)) 或者写成 #define min(a,b) (a<b?a:b) , 对于这道题 都可以。
不过我还是建议 用前一种,比较保险,因为用 define 预定义函数,必须要将 参数 都加括号。
至于为什么,我举一个经典的例子:
#define function(a) a*a
调用的时候 function(2+2) 就会 出错,应该是16, 它输出8,这里把括号扩在外面都没用,要((a)*(a)),把参数作为一个整体。
我在做这道题的时候, 算法方面没什么问题,但是一些小的细节 困了我好久,每次调试 都 感觉好烦。但 渐渐的,我发现,只有自己亲手写代码,调试,发现错误,水平才会提高。照着别人代码写,很多问题 和 细节 都会 被略去。 所以,我建议,可以借鉴别人的思想,但 代码一定要自己敲,自己还原算法。
相关文章推荐
- curl返回常见错误码
- mixed content/display——https载入http资源的绕过
- C++11 智能指针
- 让SSH自动帮你查找上次输入的命令
- Redhat6.5 yum源配置方法
- 服务器网卡收包性能测试
- 可变VS不可变数组
- 微信开发入门-2
- android架构网址
- Struts2+Hibernate分页显示实例
- PG主从流复制WAL被覆盖解决方式
- 极光推送的初步配置及其使用
- 快速教程:在2D空间中使用四叉树实现碰撞检测
- 安卓源代码修改之framework下面长按power键,修改安卓原生的关机、重启界面(一)
- C++第一次实验+1
- Cron表达式
- java运行时数据区划分
- 微信开发入门-1
- 由于SSH配置文件的不匹配,导致的Permission denied (publickey)及其解决方法
- CodeForces 622A Infinite Sequence