poj1122&&zoj1053 FDNY to the Rescue! ——最短路入门题_Dijkstra算法

题目链接:http://poj.org/problem?id=1122  http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=53

题目大意:

  给定一个有向图,一个终点S,求多个点到这个点S的最短距离和对应的路径,把最短路排序后输出。

题目思路:

  点的范围是20.可以一个一个用Dijkstra。。唯一的新意就是有多个点还需要按照路径长度排序,同时还要输出对应的路径,考的就是代码能力。用结构体存就可以。注意是有向图,开始就以为是无向图,怎么算最短路都不对。。赶脚这题不难,没什么思维难度,但是做OJ上这题的人却比较少,可能有一个原因,题目比较长,然后读完题目之后觉得没什么意思就不做了。。很简单的一个东西搞这么长的题目,也许就是考的读题吧。。貌似如果不是看的书上的翻译,我也没耐心读题。。。唉,读题确实是关键的一关。

  然后这道题目,Poj上是单case,比较好过,然后数据也貌似比较弱,因为是单case,所以有一个输入的细节就特别好处理。开始Poj一下就过了,还沾沾自喜,结果把单case换成多case的时候,在zoj上交就Segmentation Fault……原来我最初处理输入个数不确定的数字的时候用了 while(~scanf())这种方法,很显然,这货只适用于单case。然后就想,该怎么处理这种输入数字个数不确定的输入呢?看了网上的一个思路,http://blog.csdn.net/yzldw333/article/details/7858172 哈哈,原来这么简单,就是以前做过的么,按照字符串处理就行了,,,好吧,,原来自己就是怕麻烦,这种方法想都没想。。然后就改了,,还是Segmentation Fault……继续调试,查错。。忍不住看了一下别人的代码,http://www.cnblogs.com/372465774y/archive/2012/11/19/2777552.html 一个注释提示了我,“这题给的字符真的是:\t '    '”好吧……我还真没注意到,虽然读题的时候注意到了,但是写代码的时候就想当然地只考虑空格,,像以前那样……思维定式啊。。然后就过了。。

  Segmentation Fault的原因是访问了非法内存,在新的OJ上如果用的是Linux的话,归在Runtime Error一类里面。多谢zsl!

 

Poj代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cctype>
 6 #include <stack>
 7 #include <queue>
 8 #include <map>
 9 #include <set>
10 #include <vector>
11 #include <cmath>
12 #include <algorithm>
13 #define lson l, m, rt<<1
14 #define rson m+1, r, rt<<1|1
15 using namespace std;
16 typedef long long int LL;
17 const int MAXN =  0x7fffffff;
18 const int  MINN =  -0x7fffffff;
19 const double eps = 1e-9;
20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
21   {1,1},{1,-1},{-1,-1}};
22 
23 const int MAX = 20;
24 int edge[MAX][MAX], n, dist[MAX], path[MAX], end;
25 bool S[MAX];
26 typedef struct Fire {
27   int street[MAX], len, start, E;
28   bool operator < (const Fire &other) const {
29     return len < other.len;
30   }
31 }Fire;
32 Fire fire[MAX];
33 void Dijkstra(int u0, Fire &su) {
34   int i, j, k, u, Min;
35   for (i = 1; i <= n; ++i) {
36     dist[i] = edge[u0][i]; S[i] = false;
37     if (i != u0 && edge[u0][i] != MAXN) path[i] = u0;
38     else path[i] = -1;
39   }
40   S[u0] = true; path[u0] = -1;
41   for (i = 1; i < n; ++i) {
42     Min = MAXN; u = u0;
43     for (j = 1; j <= n; ++j) {
44       if (S[j] == false && dist[j] < Min) {
45         Min = dist[j]; u = j;
46       }
47     }
48     S[u] = true;
49     for (j = 1; j <= n;++j) {
50       if (S[j] == false && edge[u][j] != MAXN) {
51         int tmp = edge[u][j] + dist[u];
52         if (tmp < dist[j]) {
53           dist[j] = tmp; path[j] = u;
54         }
55       }
56     }
57     if (u == end) break;
58   }
59   k = 0; su.street[k] = end; int ho = path[end];
60   while (ho != -1) {
61     su.street[++k] = ho; ho = path[ho];
62   }
63   su.E = k;
64   su.len = dist[end];
65 }
66 int main(void){
67 #ifndef ONLINE_JUDGE
68   freopen("poj1122.in", "r", stdin);
69 #endif
70   int i, j;
71   while (~scanf("%d", &n)) {
72     for (i = 1; i <= n; ++i) {
73       for (j = 1; j <= n; ++j) {
74         scanf("%d", &edge[i][j]);
75         if (edge[i][j] == -1) edge[i][j] = MAXN;
76       }
77     }
78     scanf("%d", &end);
79     printf("Org\tDest\tTime\tPath\n");
80     int cnt= 0, start;
81     while (~scanf("%d", &start)) {
82       fire[cnt].start = start;
83       Dijkstra(start, fire[cnt]);
84       cnt++;
85     }
86     sort(fire, fire+cnt);
87     for (i = 0; i < cnt; ++i) {
88       printf("%d\t%d\t%d\t", fire[i].start, end, fire[i].len);
89       for (j = fire[i].E; j > 0; --j) {
90         printf("%d\t", fire[i].street[j]);
91       }
92       printf("%d\n", fire[i].street[0]);
93     }
94   }
95 
96   return 0;
97 }

 

Zoj代码: 注意第86行到96行

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cctype>
  6 #include <stack>
  7 #include <queue>
  8 #include <map>
  9 #include <set>
 10 #include <vector>
 11 #include <cmath>
 12 #include <algorithm>
 13 #define lson l, m, rt<<1
 14 #define rson m+1, r, rt<<1|1
 15 using namespace std;
 16 typedef long long int LL;
 17 const int MAXN =  0x7fffffff;
 18 const int  MINN =  -0x7fffffff;
 19 const double eps = 1e-9;
 20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
 21   {1,1},{1,-1},{-1,-1}};
 22 
 23 const int MAX = 30;
 24 int edge[MAX][MAX], n, dist[MAX], path[MAX], end;
 25 bool S[MAX];
 26 typedef struct Fire {
 27   int street[MAX], len, start, E;
 28   bool operator < (const Fire &other) const {
 29     return len < other.len;
 30   }
 31 }Fire;
 32 Fire fire[MAX];
 33 void Dijkstra(int u0, Fire &su) {
 34   int i, j, k, u, Min;
 35   for (i = 1; i <= n; ++i) {
 36     dist[i] = edge[u0][i]; S[i] = false;
 37     if (i != u0 && edge[u0][i] != MAXN) path[i] = u0;
 38     else path[i] = -1;
 39   }
 40   S[u0] = true; path[u0] = -1;
 41   for (i = 1; i < n; ++i) {
 42     Min = MAXN; u = u0;
 43     for (j = 1; j <= n; ++j) {
 44       if (S[j] == false && dist[j] < Min) {
 45         Min = dist[j]; u = j;
 46       }
 47     }
 48     S[u] = true;
 49     for (j = 1; j <= n;++j) {
 50       if (S[j] == false && edge[u][j] != MAXN) {
 51         int tmp = edge[u][j] + dist[u];
 52         if (tmp < dist[j]) {
 53           dist[j] = tmp; path[j] = u;
 54         }
 55       }
 56     }
 57     if (u == end) break;
 58   }
 59   k = 0; su.street[k] = end; int ho = path[end];
 60   while (ho != -1) {
 61     su.street[++k] = ho; ho = path[ho];
 62   }
 63   su.E = k;
 64   su.len = dist[end];
 65 }
 66 int main(void){
 67 #ifndef ONLINE_JUDGE
 68   freopen("poj1122.in", "r", stdin);
 69 #endif
 70   int i, j, T;
 71   scanf("%d", &T);
 72   for (int I = 0; I < T; ++I)
 73   {
 74     scanf("%d", &n);
 75     for (i = 1; i <= n; ++i) {
 76       for (j = 1; j <= n; ++j) {
 77         scanf("%d", &edge[i][j]);
 78         if (edge[i][j] == -1) edge[i][j] = MAXN;
 79       }
 80     }
 81     scanf("%d", &end);
 82     printf("Org\tDest\tTime\tPath\n");
 83     int cnt= 0, start;
 84     getchar(); char ch[100]; gets(ch);
 85     int len = strlen(ch);
 86     for (i = 0; i < len; ++i) {
 87       while (!isdigit(ch[i])) i++;   // 果然不仅仅有空格!!
 88       start = 0;
 89       while (isdigit(ch[i]) && i < len) {
 90         start = start * 10 + (ch[i]-'0');
 91         i++;
 92       }
 93       fire[cnt].start = start;
 94       Dijkstra(start, fire[cnt]);
 95       cnt++;
 96     }
 97     sort(fire, fire+cnt);
 98     for (i = 0; i < cnt; ++i) {
 99       printf("%d\t%d\t%d\t", fire[i].start, end, fire[i].len);
100       for (j = fire[i].E; j > 0; --j) {
101         printf("%d\t", fire[i].street[j]);
102       }
103       printf("%d\n", fire[i].street[0]);
104     }
105     if (I != T-1) printf("\n");
106   }
107 
108   return 0;
109 }

  赶脚还是要认真读题啊,像今天这种细节。。就是一个致命的错误

 
posted on 2013-05-06 19:51  aries__liu  阅读(556)  评论(0编辑  收藏  举报