ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

codeforces1453 E. Dog Snacks

2020-12-06 22:01:09  阅读:228  来源: 互联网

标签:idx Snacks int ne codeforces1453 Dog cin 节点 dp


题目链接
题意 : 给你一棵树,每个点有一个零食 ,某个人从1号根节点出发,每次尽量走最近的点,最后走完回到1号点,问最小的k。
思路:本来想的是二分+check 发现不可做啊,然后看了别人的题解,原来是有规律的,这道题确实和ccpc秦皇岛的蛮像,也是用的树形dp和贪心的结合,假设我们以u为根(u不是根节点的情况),那么对于每个儿子v所要满足 k > = f [ v ] + 2 k>=f[v]+2 k>=f[v]+2
其中k是能走的最大的范围 f[v]是子节点最浅的位置,由于这个题的特殊性,每次遍历完子树,必然会停在某个叶子节点上,然后再从叶子节点转向另外一个子树,那么走的最优的方案必然是遍历完子树的最后的点停留在离u最近的叶子节点上,那么上来就会方便。然后还有个问题,为什么根节点要特判呢,因为最后回到根节点就行了,就不需要多走1步了,那么我们肯定选择走上来最困难的根的节点,也就是 f v fv fv最大的,因为如果 f v fv fv不加1就说明它要加2了,那肯定没有+1优秀。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug printf("---\n");
const int N=200010,M=2*N;
int dp[N],h[N],e[M],ne[M],idx,d[N];
void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int res=0;
void dfs(int u,int fa)
{
	if(d[u]==1 && u!=1)
	{
		dp[u]=0;
		return ;
	}
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa)	continue;
		dfs(j,u);
		dp[u]=min(dp[u],dp[j]+1);
	}
}
vector<int>v;
void dfs2(int u,int fa)
{
	int maxv=0;
	//if(u==1)
	if(d[u]==1 && u!=1)
	return ;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa)	continue;
		if(u==1)
		{
		v.push_back(dp[j]);
		}
		maxv=max(maxv,dp[j]);
		dfs2(j,u);
	}
	if(u==1)
	{
	//	cout<<v.size()<<endl; 
	res=max(res,maxv+1);
	sort(v.begin(),v.end());
	for(int i=0;i<(int)v.size()-1;i++)
	res=max(res,v[i]+2);
	}
	else
	res=max(res,maxv+2);
}
int main()
{
	ios::sync_with_stdio();
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		v.clear();
		res=0;
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)
		h[i]=-1;
		idx=0;
		for(int i=1;i<=n;i++)
		d[i]=0,dp[i]=0x3f3f3f3f;
		for(int i=0;i<n-1;i++)
		{
			int	a,b;
			cin>>a>>b;
			add(a,b);
			add(b,a);
			d[a]++,d[b]++;
		}
		dfs(1,-1);
		dfs2(1,-1); 
		cout<<res<<endl;
	 } 
	 return 0;
}
/*
3
3
1 2
1 3
4
1 2
2 3
3 4
8
1 2
2 3
3 4
1 5
5 6
6 7
5 8

*/

标签:idx,Snacks,int,ne,codeforces1453,Dog,cin,节点,dp
来源: https://blog.csdn.net/qq_45961321/article/details/110775155

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有