Edge Weight Assignment
思路
我们假定,这棵树连起来是一条链,也就是只有两个叶子,不难发现最大值就是 (n - 1) 也就是总边数。
假设一个节点直接相连着两个叶子,那么这两条边是一定是相等的,总边数要减去一,假设有三个叶子总边数减去2,以此类推。
总结边权不同的最大值就是 (n - 1 - sum limits_{i = 1} ^ {n}(直接相连的叶子的数量 - 1))
接着我们考虑总边数最小值,假设任意两个节点的距离都是偶数的话,不难发现最小值就是 (1)。
假设存在一对叶子之间的距离是奇数,那么其距离一定是 (>=3)应为 (n >= 3),所以最小值一定是3。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int head[N], to[N], nex[N], cnt = 1;
int n, num[N], is_odd[N];
void dfs(int now, int fa, int state) {
is_odd[now] = state;
for(int i = head[now]; i ; i = nex[i])
if(to[i] != fa)
dfs(to[i], now, state ^ 1);
}
void add(int x, int y) {
to[cnt] = y;
nex[cnt] = head[x];
head[x] = cnt++;
}
int main() {
// freopen("in.txt", "r", stdin);
int x, y;
scanf("%d", &n);
for(int i = 1; i < n; i++) {
scanf("%d %d", &x, &y);
add(x, y);
add(y, x);
num[x]++;
num[y]++;
}
for(int i = 1; i <= n; i++)
if(num[i] == 1) {
dfs(i, 0, 0);
break;
}
int ansmin = 1, ansmax = n - 1;
for(int i = 1; i <= n; i++)
if(num[i] == 1 && is_odd[i] == 1) {
ansmin = 3;
break;
}
for(int i = 1; i <= n; i++) {
int sum = 0;
for(int j = head[i]; j; j = nex[j]) {
if(num[to[j]] == 1)
sum++;
}
if(sum) ansmax -= (sum - 1);
}
printf("%d %d
", ansmin, ansmax);
return 0;
}