[ AGC004 F ] Namori
题目
思路
代码
#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;
}