cf1182E Complete Mirror

  • 可以得到一个结论, 可行的点要么是直径端点, 要么是直径中点, 要么是直径中点引出的链中最短的端点
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#define mmp make_pair
#define ll long long
#define M 100010
using namespace std;
int read() {
    int nm = 0, f = 1;
    char c = getchar();
    for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    return nm * f;
}
vector<int> to[M];
int n;
int sta[M], tp, a, b, mid, maxx;
int du[M], deep[M], af[M];
vector<int> note[M];

void dfss(int now, int f) {
    deep[now] = deep[f] + 1;
    note[deep[now]].push_back(du[now]);
    for(int i = 0; i < to[now].size(); i++) {
        int vj = to[now][i];
        if(vj == f) continue;
        dfss(vj, now);
    }
}

void dfs(int now, int f) {
    sta[++tp] = now;
    if(tp > maxx) {
        maxx = tp;
        b = now, mid = sta[(tp + 1) >> 1];
    }
    for(int i = 0; i < to[now].size(); i++) {
        int vj = to[now][i];
        if(vj == f) continue;
        dfs(vj, now);
    }
    tp--;
}

void check(int x) {
    for(int i = 1; i <= n; i++) vector<int>().swap(note[i]);
    dfss(x, 0);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j < note[i].size(); j++) {
            if(note[i][j] != note[i][j - 1]) return;
        }
    }
    cout << x << "\n";
    exit(0);
}

void work(int now, int f) {
    deep[now] = deep[f] + 1;
    if(du[now] > 2) return;
    if(du[now] == 1) {
        if(maxx > deep[now]) {
            maxx = deep[now], a = now;
        }
        return;
    }
    for(int i = 0; i < to[now].size(); i++) {
        int vj = to[now][i];
        if(vj == f) continue;
        work(vj, now);
    }
}

int main() {
    n = read();
    for(int i = 1; i < n; i++) {
        int vi =  read(), vj = read();
        to[vi].push_back(vj);
        to[vj].push_back(vi);
        du[vi]++;
        du[vj]++;
    }
    a = 1;
    dfs(1, 0);
    maxx = 0;
    a = b;
    dfs(a, 0);
    check(a);
    check(b);
    check(mid);
    maxx = 0x3e3e3e3e;
    for(int i = 0; i < to[mid].size(); i++) {
        int vj = to[mid][i];
        work(vj, mid);
    }
    check(a);
    cout << "-1\n";
    return 0;
}
上一篇:complete完成量——实例分析


下一篇:Markdown语法