Edge Weight Assignment CodeForces - 1339D(思维+贪心)

You have unweighted tree of n vertices. You have to assign a positive weight to each edge so that the following condition would hold:

For every two different leaves v1 and v2 of this tree, bitwise XOR of weights of all edges on the simple path between v1 and v2 has to be equal to 0.
Note that you can put very large positive integers (like 10(1010)).

It’s guaranteed that such assignment always exists under given constraints. Now let’s define f as the number of distinct weights in assignment.
在这里插入图片描述
In this example, assignment is valid, because bitwise XOR of all edge weights between every pair of leaves is 0. f value is 2 here, because there are 2 distinct edge weights(4 and 5).
In this example, assignment is invalid, because bitwise XOR of all edge weights between vertex 1 and vertex 6 (3,4,5,4) is not 0.
在这里插入图片描述
What are the minimum and the maximum possible values of f for the given tree? Find and print both.

Input
The first line contains integer n (3≤n≤105) — the number of vertices in given tree.

The i-th of the next n−1 lines contains two integers ai and bi (1≤ai<bi≤n) — it means there is an edge between ai and bi. It is guaranteed that given graph forms tree of n vertices.

Output
Print two integers — the minimum and maximum possible value of f can be made from valid assignment of given tree. Note that it’s always possible to make an assignment under given constraints.

Examples
Input
6
1 3
2 3
3 4
4 5
5 6
Output
1 4
Input
6
1 3
2 3
3 4
4 5
4 6
Output
3 3
Input
7
1 2
2 7
3 4
4 7
5 6
6 7
Output
1 6
Note
In the first example, possible assignments for each minimum and maximum are described in picture below. Of course, there are multiple possible assignments for each minimum and maximum.
在这里插入图片描述

In the second example, possible assignments for each minimum and maximum are described in picture below. The f value of valid assignment of this tree is always 3.
在这里插入图片描述

In the third example, possible assignments for each minimum and maximum are described in picture below. Of course, there are multiple possible assignments for each minimum and maximum.
在这里插入图片描述
思路:最小值:个人感觉最小值是比较简单的。因为如果两个叶子节点之间是偶数长度的话,那么这两个叶子节点之间的路径都为1就可以。如果说是奇数长度的话,那就只能是3个数字才可以满足。为什么是这样呢?假如路径长度是5的话,那么前3个路径都可以设置为1,但是后面两个就不能设置为1了,必须一个是2,一个是3,只有这样才满足。因此最小值非1即3,找到一个叶子节点dfs一遍就可以找出来。
最大值:最大值不太好懂。对于两个叶子节点,在什么情况下,他们之间的路径必须都是同一个数?答案是这两个叶子节点之间的路径长度为2时,如图所示:
在这里插入图片描述
1和2来说,他们之间的路径长度为2,那么他们的路径权值必须一样才可以,否则不行。如果他们之间的路径长度>2,肯定会找出一种方式,使得路径权值不一样,并且异或之后为0的。因此,我们找出每一个节点所连接的叶子节点个数,这些叶子节点相连的路径权值必须一样。假设有cnt个叶子节点,那么就有cnt条边,这些边的权值都一样,也就是牺牲了cnt-1条边的贡献。一开始最多有n-1个数字,最终的答案也就是n-1-Sum(max(0,cnt-1))。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=1e5+100;
struct edge{
	int to,next;
}e[maxx<<1];
int head[maxx<<1],deg[maxx];
int n,tot;

inline void add(int u,int v)
{
	e[tot].next=head[u],e[tot].to=v,head[u]=tot++;
}
inline void init()
{
	memset(head,-1,sizeof(head));
	memset(deg,0,sizeof(deg));
	tot=0;
}
inline void dfs(int u,int f,int &z,int num)
{
	if(z) return ;
	if(deg[u]==1&&num==1)
	{
		z=1;
		return ;
	}
	for(int i=head[u];i!=-1;i=e[i].next)
	{
		int to=e[i].to;
		if(to==f) continue;
		dfs(to,u,z,num^1);
		if(z) return ;
	}
}
int main()
{
	scanf("%d",&n);
	int x,y,z;
	init();
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
		deg[x]++,deg[y]++;
	}
	int _min=1,_max=n-1;
	for(int i=1;i<=n;i++)
	{
		if(deg[i]==1)
		{
			z=0;
			dfs(i,i,z,0);
			if(z&1) _min=3;
			break;
		}
	}
	for(int i=1;i<=n;i++) 
	{
		int cnt=0;
		for(int j=head[i];j!=-1;j=e[j].next) if(deg[e[j].to]==1) cnt++;
		_max-=max(0,cnt-1);
	}
	printf("%d %d\n",_min,_max);
	return 0;
}

努力加油a啊,(o)/~

发布了668 篇原创文章 · 获赞 118 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/105505919