Edge Weight Assignment

Edge Weight Assignment

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\n", ansmin, ansmax);
    return 0;
}
posted @ 2020-04-29 15:48  lifehappiness  阅读(88)  评论(0编辑  收藏  举报