您的位置:首页 > 其它

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)),把参数作为一个整体。

我在做这道题的时候, 算法方面没什么问题,但是一些小的细节 困了我好久,每次调试 都 感觉好烦。但 渐渐的,我发现,只有自己亲手写代码,调试,发现错误,水平才会提高。照着别人代码写,很多问题 和 细节 都会 被略去。 所以,我建议,可以借鉴别人的思想,但 代码一定要自己敲,自己还原算法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: