Edge Weight Assignment CodeForces - 1338B

原题链接
考察:构造+贪心
思路:
  最小值很容易想,如果叶子结点之间的距离都为偶数,那么minv = 1.如果存在一个奇数那么minv = 3.
  最大值本蒟蒻没想到,实际上只要两个叶子结点之间距离==2,那么这两个叶子结点之间必同权值.如果dist>2,那么一方可选择的值就很多,必然不会相同.这个不需要真的去赋值,只需要统计相同父节点叶子节点数量.
  最大值取值n-1,假设相同父节点叶子节点数量nums.那么最大值 = n-1-(nums-1).

  求叶子节点之间距离奇偶本蒟蒻只想到了LCA,结果用染色就行了,果然还是太菜啊!

Code

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int N = 100010;
int n,h[N],idx,color[N],depth[N],d[N];
vector<int> Node;
struct Road{
	int to,ne,w;
}road[N<<1];
void add(int a,int b)
{
	road[idx].to = b,road[idx].ne =h[a],h[a] = idx++;
}
void bfs(int s)
{
	queue<int> q;
	q.push(s);
	memset(depth,0x3f,sizeof depth);
	depth[s] = 1;
	while(q.size())
	{
		int u = q.front();
		q.pop();
		for(int i=h[u];~i;i=road[i].ne)
		{
			int v = road[i].to;
			if(depth[v]>depth[u]+1)
			{
				depth[v] =depth[u]+1;
				color[v] = 1^color[u];
				q.push(v);
			}
		}
	}
}
int main()
{
	scanf("%d",&n);
	memset(h,-1,sizeof h);
	int minv = 1,maxn = n-1;
	for(int i=1;i<n;i++)
	{
		int a,b; scanf("%d%d",&a,&b);
		add(a,b); add(b,a);
		d[a]++,d[b]++;
	}
	for(int i=1;i<=n;i++) 
	 if(d[i]==1) Node.push_back(i);
	bfs(Node.back());
	memset(d,0,sizeof d);
	for(int i=0;i<Node.size();i++)
	{
		int a = Node[i];
		d[road[h[a]].to]++;
		if(color[a]!=color[Node.back()]) minv = 3;
	}
	for(int i=1;i<=n;i++)
	  maxn -= max(d[i]-1,0);
	printf("%d %d\n",minv,maxn);
	return 0;
}
posted @ 2021-05-27 02:47  acmloser  阅读(28)  评论(0编辑  收藏  举报