zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    计算机网络--Socket
    计算机网络-p2p
    ubuntu安装redis
    解决beego在ubuntu下连接mysql与重置mysql密码
    二叉树的结点计算题
    极限之无穷小的比阶
    数据结构上机实验(7)
    线代中两个列向量的小知识
    中值定理结合行列式计算
    n阶行列式计算
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12955937.html
Copyright © 2011-2022 走看看