ICPC 2019-2020 North-Western Russia Regional Contest E. Equidistant(分层)

Posted ssummerzzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ICPC 2019-2020 North-Western Russia Regional Contest E. Equidistant(分层)相关的知识,希望对你有一定的参考价值。

Equidistant

思路:我们首先可以想到,如果存在点x使得其他队伍到达这个城市距离相同,可以看作一个四面八方往上走楼梯的方式,通过走楼梯,他们慢慢汇聚到一起,直到汇聚到x点,则我们可以通过bfs来进行分层,从队伍点出发bfs,之后我们只需要模拟汇聚的方式,当然,我们只能走上一层的点,不能退,不能跨,如果最后可以汇聚到点x,即cnt[x] == m,说明YES,反之,NO。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <queue>
#include <map>

using namespace std;

#define ll long long
#define pb push_back
#define fi first
#define se second

const int INF = 1e9;

vector<vector<int > > E;
vector<int > app;
vector<int > d;
vector<int > vis;
vector<int > cnt;

void bfs2(int n){
    fill(vis.begin(), vis.end(), 0);
    queue<int > que;
    for(int i = 1; i <= n; ++i){
        if(app[i]){
            que.push(i);
            vis[i] = 1;
        }
    }

    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(auto v : E[u]){
            if(d[v] != d[u] + 1) continue; //只能下一层到上一层
            //printf(" u = %d v = %d
", u, v);
            //vis[v] = 1;
            cnt[v] += cnt[u]; //汇聚
            if(!vis[v]){
                que.push(v);
                vis[v] = 1;
            }
        }
    }
}

void bfs1(int n ){
    queue<int > que;
    for(int i = 1 ;i <= n; ++i){
        if(app[i]) {
            que.push(i);
            d[i] = 1;
            vis[i] = 1;
        }
    }

    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(auto v : E[u]){
            if(vis[v]) continue;
            vis[v] = 1;
            d[v] = d[u] + 1;
            que.push(v);
        }
    }
}

void solve(){
    int n, m;
    scanf("%d%d", &n, &m);
    E.resize(n + 10, vector<int >());
    d.resize(n + 10, 0);
    vis.resize(n + 10, 0);
    cnt.resize(n + 10, 0);
    app.resize(n + 10, 0); 
    int u, v;
    for(int i = 0; i < n - 1; ++i){
        scanf("%d%d", &u, &v);
        E[u].pb(v);
        E[v].pb(u);
    }
    //标记城市
    int city;
    for(int i = 0; i < m; ++i){
        scanf("%d", &city);
        app[city] = 1;
        cnt[city] = 1;
    }

    bfs1(n);//分层
    bfs2(n);//走层
    // for(int i = 1; i <= n; ++i) printf("u = %d d = %d
", i, d[i]);
    // cout << endl;
    // for(int i = 1; i <= n; ++i) cout << cnt[i] << " ";
    // cout << endl;
    int inx = -1;
    for(int i = 1; i <= n; ++i){
        if(cnt[i] == m){
            inx = i; break;
        }
    }
    if(inx == -1) printf("NO
");
    else printf("YSE
%d
", inx);
}

int main(){

    // ios::sync_with_stdio(false);
    // cin.tie(0); cout.tie(0);
    // freopen("C:\Users\admin\Desktop\input.txt", "r", stdin);
    // freopen("C:\Users\admin\Desktop\output.txt", "w", stdout);
    solve();
    //cout << "not error" << endl;
    return 0;
}

 

以上是关于ICPC 2019-2020 North-Western Russia Regional Contest E. Equidistant(分层)的主要内容,如果未能解决你的问题,请参考以下文章

2019-2020 ICPC, Asia Jakarta Regional Contest

2019-2020 ICPC, Asia Jakarta Regional Contest C. Even Path

2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest

2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings

2019-2020 ACM-ICPC Brazil Subregional Programming Contest (7/10)

比赛:ICPC Asia Taipei-Hsinchu Regional 2019 2020.4.1