题目链接:
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 }