zoukankan      html  css  js  c++  java
  • zoj2913 Bus Pass ——BFS入门题

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1912

    题目大意:

      有很多个地区,有几条公交线经过一些地区,求出一个地区,满足,使这个地区到这些公交线上的所有公交站的距离中的最大值,最小。(这里的距离指的是两点之间的边数)

    思路:

      对于这些公交站中的每一个点,BFS,求出出当前点外,其他所有点到这个点的最小距离,然后对于公交站上的其他点,也进行同样地操作,不断更新所有点到公交站上的当前点的最小距离的较大值,然后遍历所有点,求出距离最小的一个点。用res1数组存储。res数组的作用是对于公交线上的每个点,BFS其他点的时候,临时存放其他点到这个公交站的最小距离,然后在与res1数组进行比较,用来更新res1数组。

    注意:

      visited数组,标记这个是不是被访问过,并且标记的顺序要想清楚!把这个点入队的时候就要标记它被访问了,而不是它出队的时候再标记!这是因为,如果两天点同时和一个点相邻,如果等点出队的时候在标记的话,就会产生这个点被访问两次的情况,这个问题让我纠结了一个星期……我去……

    比如这种情况,C和A,B同时相邻,假如:先访问A,res[B] = res[C] = 2,把A标记,然后出队;再访问B,res[C] = 3,C的值显然是不对的,所以,当把B,C两个点入队的时候,就把他们标记为已经访问,就可以了……

      做这个题目感触挺大的,首先,写代码要全神贯注,不能有一点儿疏忽,否则很容易犯那种超级难找出来的隐蔽的错误,一定要考虑明白再写;然后就是数组的下标什么的,养成好习惯,到底什么时候该从0开始,什么时候该从1开始,我觉得从1开始比较保险,因为有的时候会用到编号,比如这道题目,点的标号从1开始;最后就是思考这种题目应该如何存储题目给的信息,这个东西是看的书上的思想;

      自己写代码比看着人家的代码写感觉和收获是完全不一样的。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <cmath>
     9 #include <algorithm>
    10 #define lson l, m, rt<<1
    11 #define rson m+1, r, rt<<1|1
    12 using namespace std;
    13 typedef long long int LL;
    14 const int MAXN =  0x3f3f3f3f;
    15 const int  MIN =  -0x3f3f3f3f;
    16 const double eps = 1e-9;
    17 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    18   {1,1},{1,-1},{-1,-1}};
    19 const int MAX = 10000+10;
    20 int edge[MAX][11], res[MAX], res1[MAX], ve, pa, mz[MAX];
    21 bool visited[MAX];
    22 queue<int> qt;
    23 void bfs(int id){
    24   res[id] = 1; qt.push(id); int te;
    25   visited[id] = true;
    26   while (!qt.empty()){
    27     te = qt.front();  qt.pop();
    28     for (int k = 1; k <= mz[te]; ++k){
    29       if (!visited[edge[te][k]]){
    30         qt.push(edge[te][k]);
    31         res[edge[te][k]] = max(res[edge[te][k]], res[te] + 1);
    32         visited[edge[te][k]] = true;
    33       }
    34     }
    35   }
    36   for (int k = 1; k <= MAX; ++k) {
    37     res1[k] = max(res1[k], res[k]);
    38   }
    39 }
    40 int main(void){
    41 #ifndef ONLINE_JUDGE
    42   freopen("zoj2913.in", "r", stdin);
    43 #endif
    44   int t;scanf("%d", &t);
    45   while (t--){
    46     scanf("%d%d", &ve, &pa); int n;
    47     memset(mz, 0, sizeof(mz));
    48     for (int i = 1; i <= ve; ++i){
    49       scanf("%d", &n); scanf("%d", &mz[n]);
    50       for (int j = 1; j <= mz[n]; ++j){
    51         scanf("%d", &edge[n][j]);
    52       }
    53     }
    54     int id;
    55     for (int i = 1; i <= MAX; ++i) res1[i] = -1;
    56     for (int i = 1; i <= pa; ++i){
    57       scanf("%d", &n);
    58       for (int j = 1; j <= n; ++j){
    59         scanf("%d", &id);
    60         memset(visited, false, sizeof(visited));
    61         for (int k = 1; k <= MAX; ++k) res[k] = -1;
    62         bfs(id);
    63         for (int k = 1; k <= MAX; ++k)
    64           res1[k] = max(res1[k], res[k]);
    65       }
    66     }
    67     int fu = MAX, fid;
    68     for (int i = 1; i <= MAX; ++i){
    69       if (res1[i] != -1 && fu > res1[i]){
    70         fu = res1[i]; fid = i;
    71       }
    72     }
    73     printf("%d %d\n", fu, fid);
    74   }
    75 
    76   return 0;
    77 }

      不管怎么样,过程如何纠结,想了多少时间,写了多少遍,最后还是1A了……

  • 相关阅读:
    OCP 071【中文】考试题库(cuug整理)第39题
    OCP 071【中文】考试题库(cuug整理)第38题
    OCP 071【中文】考试题库(cuug整理)第37题
    OCP 071【中文】考试题库(cuug整理)第36题
    OCP 071【中文】考试题库(cuug整理)第35题
    OCP 071【中文】考试题库(cuug整理)第34题
    POST 数据的丢失 +号
    Windows下使用 sqlmap 测试注入
    多部电梯的测试用例
    如何测试购物车?
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3017623.html
Copyright © 2011-2022 走看看