[ AGC004 F ] Namori

题目

Atcoder

思路

001.png
002.png
003.png

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int n, m, c[N], k[N];
int h[N], val[N << 1], ptr[N << 1], idx;
void add(int a, int b) { val[idx] = b, ptr[idx] = h[a], h[a] = idx++; }
int S, T, odd; // 环一条边的两端点, 是否为奇环
void DFS_init(int u, int fa) {
    for (int i = h[u], v = val[i]; i != -1; i = ptr[i], v = val[i])
        if (v == fa) continue;
        else if (c[v] != 0) {
            if (c[v] == c[u]) odd = true;
            S = u, T = v;
        } else c[v] = -c[u], DFS_init(v, u);
}
void DFS_calc(int u, int fa) {
    for (int i = h[u], v = val[i]; i != -1; i = ptr[i], v = val[i])
        if (v == fa || (v == S && u == T) || (v == T && u == S)) continue;
        else DFS_calc(v, u), k[u] += k[v], c[u] += c[v];
}
int s[N], cnt;
int main() {
    cin >> n >> m;
    memset(h, -1, sizeof h);
    if (n & 1) return cout << "-1" << endl, 0;
    for (int i = 1, a, b; i <= m; i++) 
        cin >> a >> b, add(a, b), add(b, a);
    c[1] = 1, DFS_init(1, 0); // 把 1 染成黑色, DFS初始化
    long long res = 0, sum = 0;
    for (int i = 1; i <= n; i++) sum += c[i];
    if (m == n - 1 && sum != 0) return cout << -1 << endl, 0;
    if (m == n) {
        if (odd) {
            if (sum & 1) return cout << -1 << endl, 0;
            res += abs(sum >> 1);
            c[S] -= sum >> 1, c[T] -= sum >> 1;
        } else if (sum != 0) return cout << -1 << endl, 0;
        else k[S] = 1, k[T] = -1;
    }
    DFS_calc(1, 0);
    for (int i = 1; i <= n; i++)
        if (k[i]) s[++cnt] = k[i] * c[i];
        else res += abs(c[i]);
    s[++cnt] = 0;
    sort(s + 1, s + cnt + 1);
    for (int i = 1; i <= cnt; i++) 
        res += abs(s[i] - s[(1 + cnt) >> 1]);
    cout << res << endl;
    return 0;
}
posted @ 2021-05-20 17:58  Protein_lzl  阅读(52)  评论(0编辑  收藏  举报