• 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;
    }
  • 相关阅读:
    bzoj 1098 [POI2007] 办公楼 biu
    「 Luogu P2574 」 XOR的艺术——线段树
    「 Luogu P2801 」 教主的魔法——分块
    Luogu P1438 无聊的数列
    「 Luogu P2420 」 让我们异或吧
    「 SPOJ GSS3 」 Can you answer these queries III
    「 HDOJ P2227 」 Find the nondecreasing subsequences
    「 HDOJ P3887 」 Counting Offspring
    一些性质及公式
    OI杂记
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12955937.html
Copyright © 2020-2023  润新知