CF1338B Edge Weight Assignment
根据异或的性质,,如果A到B的路径和A到C的路径的异或和都是零
那么B到C的也都是零
所以说嘛,我们只要考虑从一个叶子节点外走就可以了
如果这一个叶子节点到其他叶子节点的路径都是偶数,,那么全设为1就是一种很好的方案
如果有奇数的路径,那么再搞出两个数,比如说2和3,就能构造出来了
那么求最大值呢?
如果两个叶子节点共享父亲,那么他们的到父亲的路径值只能一样。剩下的可以随便取
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#define lll long long
using namespace std;
int n;
struct e{
int to;
int ne;
}ed[200005];
int ans;
int du[100001];
int dis[100001];
int head[100001];
int p;
void add(int f,int to){
p++;
ed[p].to=to;
ed[p].ne=head[f];
head[f]=p;
}
void dfs(int x,int r,int f){
if(du[x]==1&&x!=r){
if(dis[x]%2==1){
ans=3;
}
return ;
}
for(int i=head[x];i;i=ed[i].ne){
int v=ed[i].to;
if(v==f) continue;
dis[v]=dis[x]+1;
dfs(v,r,x);
}
}
int x,y;
int main(){
cin>>n;
ans=1;
for(int i=1;i<n;++i){
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
du[x]++;
du[y]++;
}
for(int i=1;i<=n;++i){
if(du[i]==1){
dfs(i,i,i);
break;
}
}
cout<<ans<<" ";
ans=n-1;
for(int i=1;i<=n;++i){
int f=0;
for(int j=head[i];j;j=ed[j].ne){
if(du[ed[j].to]==1){
if(!f){
f=1;continue;
}
else{
ans--;
}
}
}
}
cout<<ans;
return 0;
}