cf 1037D BFS

$des$
一个 n 个点 m 条边的无向连通图从 1 号点开始 bfs,可能得到的 bfs 序有很多,
取决于出边的访问顺序。现在给出一个 1 到 n 的排列,判断是否可能是一个 bfs 序。

$sol$
对于每个节点,令其权值为在给定序列中的位置。
然后从 1 号点开始正常的 bfs,出边的访问顺序按照权值从小到大访问。
最后将得到的 bfs 序与给定序列比较,若完全一致则是合法的。

$code$

#include <bits/stdc++.h>

using namespace std;

#define gc getchar()
inline int read() {
    int x = 0; char c = gc;
    while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
    return x;

}

#define LL long long
#define Rep(i, a, b) for(int i = a; i <= b; i ++)

const int N = 2e5 + 10;

int A[N];
int n;
vector <int> V[N];
int W[N];
int B[N], js; 
bool use[N];
int ls[N], len;

bool Cmp(int a, int b) {
    return W[a] < W[b];
}

void Bfs(int s) {
    queue <int> Q;
    use[s] = 1;
    Q.push(s);
    while(!Q.empty()) {
        int tp = Q.front();
        B[++ js] = tp;
        Q.pop();
        len = 0;
        int S = V[tp].size();
        Rep(i, 0, S - 1) {
            int v = V[tp][i];
            if(use[v]) continue;
            use[v] = 1;
            ls[++ len] = v;
        }
        sort(ls + 1, ls + len + 1, Cmp);
        Rep(i, 1, len) Q.push(ls[i]);
    }
}

int main() {
    n = read();
    Rep(i, 1, n - 1) {
        int u = read(), v = read();
        V[u].push_back(v), V[v].push_back(u);
    }
    Rep(i, 1, n) A[i] = read();
    Rep(i, 1, n) W[A[i]] = i;
    Bfs(1);
    
    Rep(i, 1, n) {
        if(A[i] != B[i]) {
            cout << "No";
            return 0;    
        }
    }
    cout << "Yes";
    
    return 0;
}

 

posted @ 2018-10-11 17:37  xayata  阅读(191)  评论(0编辑  收藏  举报