CF1338 B. Edge Weight Assignment

Karima ·
更新时间:2024-09-21
· 743 次阅读

CF1338 B. Edge Weight Assignment 题意

一棵n个结点的树,求最小和最大需要多少个不同的路径来构造树的路径权值,使得任意两片叶子的路径异或和为0。

思路

首先这是一棵无根树,以其任意一个叶子结点为根。(避免讨论)
首先考虑最小,最小要么为1要么为3。
为1的情况是任意结点到根节点的距离为偶数。
为3的情况是只要有一个结点到根结点的距离为奇数。
这里仅判断奇偶有两种写法,1是记录深度,2是利用异或。
1^1=0 0^1=1

接着考虑最大,我们发现当一个父节点直接与>1个叶子结点相连,则由于那些叶子结点到父节点的距离为1,所以他们的边权值一定相等,故这些边视为一样的。
fmax=n−1−所有直接与同一个父节点相连的叶子结点的数量f_{max}=n-1-所有直接与同一个父节点相连的叶子结点的数量fmax​=n−1−所有直接与同一个父节点相连的叶子结点的数量

#include using namespace std; typedef long long ll; typedef pairP; const double eps = 1e-8; const int NINF = 0xc0c0c0c0; const int INF = 0x3f3f3f3f; const ll mod = 1e9 + 7; const ll maxn = 1e6 + 5; const int N = 1e5 +5; ll n,maxf,minf=1,cnt=0,k=0; vector G[N]; int tot[N]; void dfs(int u,int fa,int d){ if(G[u].size()==1&&d%2==0) minf=3; for(auto c:G[u]){ if(c==fa) continue; dfs(c,u,d+1); } } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin>>n; for(int i=1;i>x>>y; G[x].push_back(y); G[y].push_back(x); } maxf=n-1; for(int i=1;i<=n;i++){ if(G[i].size()==1) tot[G[i][0]]++; } for(int i=1;i1) maxf-=tot[i]-1; } for(int i=1;i<=n;i++){ if(G[i].size()==1) {dfs(i,-1,1);break;} } cout<<minf<<" "<<maxf<<'\n'; return 0; }
作者:陆小萌



weight Edge

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章