• 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 }
  • 相关阅读:
    6月15日学习日志
    6月14日学习日志
    6月13日学习日志
    6月12日学习日志
    给建民哥的意见
    6月10日学习日志
    6月9日学习日志
    6月8日学习日志
    梦断代码读书笔记3
    第二次冲刺(六)
  • 原文地址:https://www.cnblogs.com/fzl194/p/8746663.html
Copyright © 2020-2023  润新知