ZOJ-2913 Bus Pass---BFS进阶版

题目链接:

https://vjudge.net/problem/ZOJ-2913

题目大意:

问哪个区域到公交路线上所有区域的最大距离最小

思路:

这里要求出到底是哪个区域到某些指定区域的最大距离最小,最开始想到的是每个两个点求出距离,但是点数很多,不现实,又想到枚举所有区域到指定区域的距离,此果正向求是做不到的,应该反向求解,对指定区域进行BFS,求这些区域到其他所有区域的最短路,由于道路是双向的,求出的这些最短路程也就是所有点到指定区域的最短路程,对于每个点,保存它到指定区域的最大距离,最后在这些最大距离中找出最小的距离以及该区域的编号。

有几个易错点:

vis数组在第一个节点加入队列中就要开始标记第一个元素已经入队了。

更新最大距离是,应该在每次取出头结点的时候更新不能在加入队列的时候更新(除非额外更新第一个节点),因为加入队列的事后更新的话,最开始的那个已经入队的节点的最大距离没有更新,这一点很重要

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<map>
 9 #include<set>
10 #include<sstream>
11 #include<functional>
12 using namespace std;
13 typedef long long ll;
14 const int maxn = 1e4 + 10;
15 const int INF = 1e9 + 7;
16 int T, n, m, cases;
17 int ans[maxn];//ans[i]保存着从i点出发到线路上的所有点的时间中的最大时间
18 int Map[maxn][12];//邻接表
19 bool vis[maxn];
20 struct node
21 {
22     int x, time;
23     node(){}
24     node(int x, int time):x(x), time(time){}
25 };
26 void bfs(int u)
27 {
28     queue<node>q;
29     //cout<<"---------"<<u<<"-----------"<<endl;
30     q.push(node(u, 1));
31     memset(vis, 0, sizeof(vis));
32     vis[u] = 1;
33     while(!q.empty())
34     {
35         node now = q.front();
36         q.pop();
37         ans[now.x] = max(ans[now.x], now.time);
38         //cout<<now.x<<" "<<now.time<<endl;
39         for(int i = 0; i < 12; i++)
40         {
41             if(Map[now.x][i] <= 0)break;
42             node next(Map[now.x][i], now.time + 1);
43             if(vis[next.x])continue;
44             vis[next.x] = 1;
45             //ans[next.x] = max(ans[next.x], next.time);
46             q.push(next);
47         }
48     }
49 }
50 set<int>s;
51 int main()
52 {
53     cin >> T;
54     while(T--)
55     {
56         scanf("%d%d", &n, &m);
57         s.clear();
58         memset(Map, -1, sizeof(Map));
59         memset(ans, -1, sizeof(ans));
60         int x, tot;
61         for(int i = 0; i < n; i++)
62         {
63             scanf("%d%d", &x, &tot);
64             s.insert(x);
65             for(int j = 0; j < tot; j++)
66             {
67                 scanf("%d", &Map[x][j]);
68             }
69         }
70         for(int i = 0; i < m; i++)
71         {
72             scanf("%d", &x);
73             for(int i = 0; i < x; i++)
74             {
75                 scanf("%d", &tot);
76                 bfs(tot);
77             }
78         }
79         int minsum = INF, mi;
80         for(set<int>::iterator it = s.begin(); it != s.end(); ++it)
81         {
82             if(minsum > ans[*it])
83             {
84                 mi = *it;
85                 minsum = ans[*it];
86             }
87         }
88         printf("%d %d
", minsum, mi);
89     }
90     return 0;
91 }
原文地址:https://www.cnblogs.com/fzl194/p/8746663.html