博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jdoj 1008 最短路径问题 代码及分析
阅读量:6857 次
发布时间:2019-06-26

本文共 2588 字,大约阅读时间需要 8 分钟。

    这是在一个叫做九度的OJ上面的题,这是一个典型的最短路问题。题目很简单,就只有一个要注意的地方,就是路径有可能是重复的,要把这种情况考虑进去。我就是为此WA了好几次,最后只好参考那里的BBS,才知道原来这题是要检测重复路径的。改了以后就立刻AC了!

    这题是我第一次用Dij算法做的题,因为以前都只会Floyd算法,用在这里后就TLE了一次,因为这里有1000个点,如果用Floyd的话,O(n^3)在就是最少10^9次运算了。后来想起了Dij的算法,然后根据我印象中对Dij算法的思路,打了我第一个Dij算法的代码。

    下面是我的代码,也是像其他题解一样,在旁边有注解的。如果觉得有什么不明白,或者有更好的优化方法,欢迎留言~

 

 

View Code
 1 #include<stdio.h> 
 2 #include<
string.h> 
 3 #include<stdlib.h> 
 4 
#define MAX 9999999999999999 
//
刚开始不停的WA,我以为是int不够大,所以直接用了long long
 5   
 6 typedef 
struct arc 
//
这是用来储存弧信息的结构体的定义
 7 { 
 8     
int end; 
 9     
long 
long dis; 
10     
long 
long cost; 
11     
struct arc *next; 
12 }Arc; 
13   
14 Arc *begin[
1005]; 
//
起点相同的弧放在一起,顺序查找
15 
long 
long dis[
1005]; 
//
这是从起点到各个点的距离
16 
long 
long cost[
1005]; 
//
从起点到各个点的花费
17 
int visited[
1005]; 
//
点是否确定了
18   
19 
int findmin(
int n) 
//
找出与起点的距离最小的那一点,返回点的标号
20 { 
21     
int i; 
22     
long 
long min=MAX; 
23     
int num=
0
24   
25     
for(i=
1; i<=n; i++) 
26         
if(!visited[i]&&min>dis[i])min=dis[i], num=i; 
//
如果是确定了的点就不要重复返回了
27     
return num; 
28 } 
29   
30 
int main() 
31 { 
32     
int i; 
33     
int n, m; 
34     
int a, b; 
35     
long 
long c, d; 
//
cost,distance
36     Arc *p, *tmp; 
37   
38     
while(scanf(
"
%d%d
", &n, &m)&&(n||m)) 
39     { 
40         memset(begin, 
0
sizeof(begin)); 
41         memset(visited, 
0
sizeof(visited)); 
42   
43         
for(i=
1; i<=
1003; i++) 
44             cost[i]=dis[i]=MAX; 
45         
while(m--) 
46         { 
47             scanf(
"
%d%d%lld%lld
", &a, &b, &d, &c); 
//
因为这是无向图所以两个方向都要设置
48             tmp=(Arc *)malloc(
sizeof(Arc)); 
49             tmp->next=begin[a]; 
50             tmp->end=b; 
51             tmp->dis=d; 
52             tmp->cost=c; 
53             begin[a]=tmp; 
54             tmp=(Arc *)malloc(
sizeof(Arc)); 
55             tmp->next=begin[b]; 
56             tmp->end=a; 
57             tmp->dis=d; 
58             tmp->cost=c; 
59             begin[b]=tmp; 
60         } 
61   
62         scanf(
"
%d%d
", &a, &b); 
63         c=d=MAX; 
//
额……突然发现这是多余的
64         visited[a]=
1
65         p=begin[a]; 
66         dis[a]=cost[a]=
0
67         
while(p) 
//
把各点信息放进dis和cost数组,因为可能有重复的路径,所以这里也是要比较大小的
68         { 
69             
if(dis[p->end]>dis[a]+p->dis) 
70                 dis[p->end]=dis[a]+p->dis, 
71                 cost[p->end]=cost[a]+p->cost; 
72             
else 
if(dis[p->end]==dis[a]+p->dis&&cost[p->end]>cost[a]+p->cost) 
73                 cost[p->end]=cost[a]+p->cost; 
74             p=p->next; 
75         } 
76         
while(i=findmin(n)) 
77         { 
78             visited[i]=
1
79             p=begin[i]; 
80             
while(p) 
81             { 
82                 
if(dis[p->end]>dis[i]+p->dis) 
83                     dis[p->end]=dis[i]+p->dis, 
84                     cost[p->end]=cost[i]+p->cost; 
85                 
else 
if(dis[p->end]==dis[i]+p->dis&&cost[p->end]>cost[i]+p->cost) 
86                     cost[p->end]=cost[i]+p->cost; 
87                 p=p->next; 
88             } 
89         } 
90         printf(
"
%lld %lld\n
", dis[b], cost[b]); 
91     } 
92   
93     
return 
0
94 } 

 

 

    Dij算法还是得多点用,否则到真的比赛的时候就会浪费太多时间了!

 

written by Lyon 

 

beta 1:

    可以在上面代码的第77和78行之间加上

if(i==b)break;

这样的目的是找到最小路以后直接跳出,做到剪枝优化的效果。因为根据dij算法的分析,之后找到的到达终点的路径长度只会比最小路径更长,不会再次相等。

转载于:https://www.cnblogs.com/LyonLys/archive/2012/03/13/jdoj_1008_Lyon.html

你可能感兴趣的文章
构建自己的PHP框架--构建模版引擎(2)
查看>>
vue28-2.0-过滤器
查看>>
Cocos2d-x 多点触摸
查看>>
MySql按周/月/日分组统计数据的方法
查看>>
自定义控件_VIewPager显示多个Item
查看>>
2015年年尾总结
查看>>
UI组件之AdapterView及其子类(五)ListView组件和ListActivity
查看>>
Linux编程之select
查看>>
数据库表设计--备份记录的表设计优化
查看>>
小谈业务应用架构
查看>>
JWPlayer Uncaught Error: Invalid SRT file
查看>>
mysql使用GROUP BY分组实现取前N条记录的方法
查看>>
web项目log日志查看分析->流程理解
查看>>
无线路由器连接电信光猫实现拨号上网方法
查看>>
nyoj 题目10 skiing —— 南阳oj
查看>>
Cocos2d-x游戏《雷电大战》开源啦!要源代码要资源快快来~~
查看>>
C++中的链式操作
查看>>
CNAME记录和A记录
查看>>
【Hibernate】(2)Hibernate配置与session、transaction
查看>>
POJ 2823 Sliding Window 单调队列
查看>>