题意:
给你一棵树,要你计算出一种符合条件的树最多和最少的权值不同的边的数量,对于任意的两个叶子节点他们之间的路径异或和等于 0 0 0。
-
对于最小值,如果所有叶子节点距离两两都为偶数,最小值为 1 1 1,否则为 2 2 2
-
对于最大值,初始值为 a n s = n − 1 ans=n-1 ans=n−1,如果一个节点有 > = 2 >=2 >=2 个叶子节,那只能都要合并成一个节点。
AC代码:
const int N = 1e5 + 10;
struct Edge
{
int to, nxt;
} e[N << 1];
int head[N], tote;
void add_edge(int u, int v)
{
e[++tote].to = v, e[tote].nxt = head[u];
head[u] = tote;
}
void init(int n)
{
rep(i, 0, n)
head[i] = 0;
tote = 0;
}
bool cl[N], is[N];
int dis[N];
int minn = 1, maxn;
void dfs(int s, int fa)
{
if (is[fa])
cl[s] = true;
for (int i = head[s]; i; i = e[i].nxt)
{
if (e[i].to != fa)
{
dfs(e[i].to, s);
if (dis[s] == -1)
dis[s] = dis[e[i].to] ^ 1;
else if (dis[s] != dis[e[i].to] ^ 1)
minn = 3;
if (is[e[i].to] && !cl[s])
cl[s] = true;
else if (is[e[i].to])
maxn--;
}
}
if (dis[s] == -1)
dis[s] = 0;
}
int n, in[N];
int main()
{
mem(in, 0);
mem(dis, -1);
mem(cl, 0);
mem(is, 0);
sd(n);
init(n);
rep(i, 1, n - 1)
{
int u, v;
sdd(u, v);
add_edge(u, v);
add_edge(v, u);
in[u]++, in[v]++;
}
int root;
rep(i, 1, n)
{
if (in[i] == 1)
is[i] = true, root = i;
}
maxn = n - 1;
dis[root] = 0;
dfs(root, root);
pdd(minn, maxn);
return 0;
}