poj1847 Tram(Dijkstra || Floyd || SPFA)

题目链接

http://poj.org/problem?id=1847

题意

有n个车站,编号1~n,每个车站有k个出口,车站的出口默认是k个出口中的第一个,如果不想从默认出口出站,则需要手动选择出站口。现在从车站a出发,求最少需要手动选择几次出站口才能到车站b。

思路

这题的图中没有显式给出结点之间的距离,但可以根据题意给路径添加距离,比如测试数据中的“2 2 3”表示从第1个车站默认开往第2个车站,想要开到第3个车站则需手动选择,所以我们可以令结点1到结点2的边权值为0(默认车站),结点1到结点3边权值为1(需手动选择的车站),这样就可以使用Dijkstra算法、Floyd算法或者SPFA算法求解a,b之间的最短路,a,b之间最短路的值即是需手动选择车站的次数。

代码

Dijkstra算法和Floyd算法:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int INF = 0x3f3f3f;
 8 const int N = 100 + 10;
 9 int map[N][N];
10 int dist[N];
11 int visit[N];
12 int n, a, b;
13 
14 void dijkstra()    //Dijkstra算法
15 {
16     memset(visit, 0, sizeof(visit));
17     for (int i = 1; i <= n; i++)
18         dist[i] = map[a][i];
19     dist[a] = 0;
20     visit[a] = 1;
21     int min_dist, now = a;
22     for (int i = 1; i <= n; i++)
23     {
24         min_dist = INF;
25         for (int j = 1; j <= n; j++)
26         {
27             if (!visit[j] && dist[j] < min_dist)
28             {
29                 min_dist = dist[j];
30                 now = j;
31             }
32         }
33         visit[now] = 1;
34         for (int j = 1; j <= n; j++)
35             dist[j] = min(dist[j], dist[now] + map[now][j]);
36     }
37     if (dist[b] >= INF)    //注意是dist[b]>=INF,不是dist[b]==INF
38         puts("-1");
39     else printf("%d\n", dist[b]);
40 }
41 
42 void floyd()    //Floyd算法
43 {
44     for (int k = 1; k <= n; k++)
45         for (int i = 1; i <= n; i++)
46             for (int j = 1; j <= n; j++)
47                 map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
48     if (map[a][b] >= INF)
49         puts("-1");
50     else printf("%d\n", map[a][b]);
51 }
52 
53 int main()
54 {
55     //freopen("poj1847.txt", "r", stdin);
56     while (scanf("%d%d%d", &n, &a, &b) == 3)
57     {
58         memset(map, INF, sizeof(map));
59         int k, t;
60         for (int i = 1; i <= n; i++)
61         {
62             scanf("%d", &k);
63             for (int j = 1; j <= k; j++)
64             {
65                 scanf("%d", &t);
66                 if (j == 1)
67                     map[i][t] = 0;
68                 else map[i][t] = 1;
69             }
70         }
71         dijkstra();
72         //floyd();
73     }
74     return 0;
75 }

SPFA算法:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8 
 9 struct Edge
10 {
11     int s, e, dist;
12 
13     Edge() {}
14     Edge(int s, int e, int d) :s(s), e(e), dist(d) {}
15 };
16 
17 const int INF = 0x3f3f3f;
18 const int N = 100 + 10;
19 vector<Edge> v[N];
20 int dist[N];
21 int visit[N];
22 int n, a, b;
23 
24 void spfa(int s)
25 {
26     queue<int> q;
27     memset(dist, INF, sizeof(dist));
28     memset(visit, 0, sizeof(visit));
29     q.push(s);
30     visit[s] = 1;
31     dist[s] = 0;
32 
33     while (!q.empty())
34     {
35         int s = q.front();
36         q.pop();
37         visit[s] = 0;
38         for (int i = 0; i < v[s].size(); i++)
39         {
40             int e = v[s][i].e;
41             if (dist[e] > dist[s] + v[s][i].dist)
42             {
43                 dist[e] = dist[s] + v[s][i].dist;
44                 if (!visit[e])
45                 {
46                     visit[e] = 1;
47                     q.push(e);
48                 }
49             }
50         }
51     }
52     if (dist[b] >= INF)
53         puts("-1");
54     else printf("%d\n", dist[b]);
55 }
56 
57 int main()
58 {
59     //freopen("poj1847.txt", "r", stdin);
60     while (scanf("%d%d%d", &n, &a, &b) == 3)
61     {
62         for (int i = 1; i <= n; i++)
63             v[i].clear();
64 
65         int k, t;
66         for (int i = 1; i <= n; i++)
67         {
68             scanf("%d", &k);
69             for (int j = 1; j <= k; j++)
70             {
71                 scanf("%d", &t);
72                 if (j == 1)
73                     v[i].push_back(Edge(i, t, 0));
74                 else v[i].push_back(Edge(i, t, 1));
75             }
76         }
77         spfa(a);    //求结点a到其余各点的最短路径
78     }
79     return 0;
80 }

 

posted @ 2017-12-04 20:24  ColdCode  阅读(281)  评论(0编辑  收藏  举报
AmazingCounters.com