CF1338B Edge Weight Assignment

Jennie

根据异或的性质,,如果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;
}
   

原文地址:https://www.cnblogs.com/For-Miku/p/15363948.html