zoukankan      html  css  js  c++  java
  • cf813C(bfs)

    题目链接:http://codeforces.com/problemset/problem/813/C

    题意:给出一颗树,开始时两个人 Alice 和 Bob 分别站在 1(树根)和 x 处.此后每一次操作两人都可以选择在原地不动或者移动到相邻的节点(Bob先移动);

    直至两人移到同一个位置,两人移动的总步数为 ans,Alice要使 ans 尽量小,Bob 要使 ans 尽量大,输出ans;

    思路:假设最终在 p 位置相遇,显然 p 是由先移动的 Bob 决定的,即 p 能使 ans 最大;

    用 dis1[p] 表示 1 到 p 的距离,dis2[p] 表示 x 到 p 的距离,要满足 Alice 和 Bob 在移动到 p 之前不相遇,所以有 dis1[p] > dis2[p],那么显然有 ans = 2 * dis1[p];

    即:先 bfs 出 1 和 x 到其他节点的最短距离,再遍历所有节点,对于节点 i,若满足 dis1[i] > dis2[i] ,则 ans = max(ans, 2 * dis1[i]),最终输出 ans 即可;

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <vector>
     4 #include <queue>
     5 #include <string.h>
     6 using namespace std;
     7 
     8 const int MAXN = 2e5 + 10;
     9 vector<int> mp[MAXN];
    10 bool vis[MAXN];
    11 
    12 
    13 void bfs(int dis[MAXN], int p){//求以 p 为根时其余个点到 p 的距离
    14     memset(vis, 0, sizeof(vis));
    15     int ans = 0, cnt1 = 1, cnt2 = 0;
    16     queue<int> q;
    17     q.push(p);
    18     vis[p] = true;
    19     while(!q.empty()){
    20         while(cnt1--){
    21             int cnt = q.front();
    22             q.pop();
    23             for(int i = 0; i < mp[cnt].size(); i++){
    24                 int cc = mp[cnt][i];
    25                 if(!vis[cc]){
    26                     q.push(mp[cnt][i]);
    27                     vis[mp[cnt][i]] = true;
    28                     cnt2++;
    29                 }
    30             }
    31             dis[cnt] = ans;
    32         }
    33         cnt1 = cnt2;
    34         cnt2 = 0;
    35         ans++;
    36     }
    37 }
    38 
    39 int main(void){
    40     int n, x;
    41     scanf("%d%d", &n, &x);
    42     for(int i = 0; i < n - 1; i++){
    43         int s, e;
    44         scanf("%d%d", &s, &e);
    45         mp[s].push_back(e);
    46         mp[e].push_back(s);
    47     }
    48     int dis1[MAXN], dis2[MAXN];
    49     bfs(dis1, 1);
    50     bfs(dis2, x);
    51     int ans = 0;
    52     for(int i = 1; i <= n; i++){
    53         if(dis1[i] > dis2[i] && mp[i].size() == 1){
    54             ans = max(ans, dis1[i]*2);
    55         }
    56     }
    57     cout << ans << endl;
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    联考20200725 T1 String
    联考20200723 T1 数
    联考20200722 T3 积木
    联考20200722 T2 ACT4!无限回转!
    联考20200722 T1 集合划分
    联考20200721 T2 s2mple
    联考20200721 T1 s1mple
    联考20200719 T2 寻找规律
    联考20200719 T1 合并奶牛
    联考20200718 T2 树论
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6951975.html
Copyright © 2011-2022 走看看