#ICPC 2019-2020 North-Western Russia Regional Contest E (拓扑排序)

E. Equidistant

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

In 2019 ICPC subregions structure was changed a little. Now for each subregion, we need to choose the best place for the subregion finals. To make things fair we want to choose a city in such a way that all teams will spend the same amount of time to get there.

To make things simpler we say that all teams will use trains to get to the finals. The railroad system can be represented as a tree where each city is a vertex and some pairs of cities are connected by a railroad. It takes exactly one hour to get from one city to another if they are directly connected.

You are given a description of the railroad system and the cities where teams are located. You need to choose any city that has an equal distance to all teams' cities or detect that no such city exists.

Input

The first line of the input contains two integers nn and mm — the number of cities and the number of teams (1≤m≤n≤2⋅1051≤m≤n≤2⋅105). Each of the following n−1n−1 lines contains two integers vivi and uiui — the indices of the cities connected by the ii-th railroad (1≤vi,ui≤n1≤vi,ui≤n). It is guaranteed that for each pair of cities there is exactly one simple path connecting them.

The next line contains mm integers c1,c2,…,cmc1,c2,…,cm — the cities of the teams (1≤ci≤n1≤ci≤n). All teams are located in different cities.

Output

If it is impossible to choose a city fairly, output a single word "NO". Otherwise, output a the word "YES" at the first line. The second line should contain a single integer — the city where subregion finals should be held. If there is more than one solution, output any of them.

Examples

input

Copy

6 3
1 2
2 3
3 4
4 5
4 6
1 5 6

output

Copy

YES
3

input

Copy

2 2
1 2
1 2

output

Copy

NO

题目大意 :

输入一棵树, 标记其中的K个点, 找到树上的某个点, 使该点到所有标记的点的距离相等并输出该点编号, 如果有多个输出任意一个,如果不存在, 输出NO

思路 :

不难想到要找的那个点一定在标记点的  “中间” , 所以先拓扑排序, 将其余的干扰点全部去掉, 只保留一棵子树, 叶子全部为标记的点, 此时再对新树进行拓扑排序, 并对每个点记录一个值, 表示距离, 若存在距离不相等的情况, 则不成立。注意特判一个点的情况

Accepted code

#include<bits/stdc++.h>
using namespace std;
 
#define sc scanf
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
 
set <int> e[MAXN << 1];
int dep[MAXN], dp[MAXN], n, k;
int pre[MAXN], le;
bool vis[MAXN], vist[MAXN];
void topsort() {
    queue <int> q;
    for (int i = 1; i <= n; i++) {
        if (dep[i] == 1 && !vis[i]) {
            q.push(i);
            dep[i]--;
        }
    }
    while (!q.empty()) {
        int now = q.front(); q.pop();
        set <int> :: iterator it;
        for (it = e[now].begin(); it != e[now].end();) {
            int vi = *it;
            it++;
            dep[vi]--;
            if (!vis[vi] && dep[vi] == 1) q.push(vi);
            e[now].erase(vi);
            e[vi].erase(now); // 删除干扰点
            le++;
        }
    }
}
void Topsort() {
    queue <int> q;
    bool flag = true;
    int ans = 0, max_ = -INF, sum = 0;
    for (int i = 1; i <= k; i++) dep[pre[i]]--, q.push(pre[i]), dp[pre[i]] = 1, vist[pre[i]] = true, sum++;
    if (k == n - le) { cout << "NO" << endl; return; } // 全部覆盖
    while (!q.empty()) {
        int now = q.front(); q.pop();
        vist[now] = true;
        if (dp[now] > max_) max_ = dp[now], ans = now;
        for (auto it : e[now]) {
            int vi = it;
            if (vist[vi]) continue;
            dep[vi]--;
            if (vis[vi]) flag = false;
            if (dep[vi] == 1) q.push(vi);
            if (!dp[vi]) dp[vi] = dp[now] + 1;
            else if (dp[vi] != dp[now] + 1) flag = false; // 距离不相等
        }
        if (!flag) break;
    }
    if (!flag) cout << "NO" << endl;
    else
        cout << "YES" << endl << ans <<  endl;
}
 
int main()
{
    cin >> n >> k;
    for (int i = 1; i < n; i++) {
        int ui, vi; sc("%d %d", &ui, &vi);
        e[ui].insert(vi);
        e[vi].insert(ui);
        dep[ui]++, dep[vi]++;
    }
    for (int i = 1; i <= k; i++) {
        sc("%d", &pre[i]);
        vis[pre[i]] = true; // 标记
    }
    if (n == 1 || k == 1) {cout << "YES" << endl << pre[1] << endl; return 0;}
    topsort(); Topsort();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43851525/article/details/103283443