【dfs】【树】机器选择

题目描述

自从省队NOI赛前集训在scz举行之后,一个名叫cs1.6.exe的文件开始在机房广泛使用起来。每天大家都要找神犇小X借移动硬盘,考里面的这个文件。
由于机房里需要考这个文件的人太多了,每天都要花一段时间一个人一个人的去拷贝。小T觉得这实在是太麻烦了,就想找一个一劳永逸的方法。
小T调查了一下,机房有n台机器,且有局域网,所有机器通过一些网线连接起来,其整个布局是一个树形结构,即任意两台机器间都有且仅有一条路径。小T想在其中某一台机器上储存这个文件,需要的同学就可以直接通过局域网来下载这个文件。
网络上信息传输是需要时间的,我们定义两台机器间数据传输的时间为连接这两台机器的路径所包含的网线数量。虽然机房里通过局域网传个文件是很快的,但对于急不可耐的同学们来说,一分一秒都是宝贵的,文件传输越快越好。所以小T要选择一台机器存储文件,使得所有机器下载这个文件需要的总时间(即最后一台机器完成下载的时间)尽可能短。
现在,你需要给出这个最短时间,以便让小T看看他的决策是否最优。

输入

第1行:一个整数n。
第2-n行:两个整数u、v,即u、v两台机器间有一条网线连接。机器从1~n编号。
输入数据保证是一个连通的树型结构。

输出

1行一个整数,即最短的时间。

输入样例
5
3 2
2 1
5 2
2 4
输出样例
1

数据范围

对于30%的数据,n≤100;
对于50%的数据,n≤1000;
对于100%的数据,2≤n≤100000。

思路

两遍dfs求出直径,然后再将直径/2就是答案了
某位巨佬说不开栈会过不了
这个思路可能有点简洁,看不懂的可以去另外一位( W J J WJJ WJJ)巨佬的blog里看
->->->机器选择

代码

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n,x,y,ans,tt,h[100005],k;
int p[100005];
struct node
{
	int w,xp;
}a[200005];
void dfs(int x,int y)
{
	p[x]=1;
	if (y>ans) ans=y,k=x;
	for (int i=h[x]; i; i=a[i].xp)
		if (!p[a[i].w]) dfs(a[i].w,y+1);
	p[x]=0;
}
int main()
{
	int size = 256 << 20;
    char*p=(char*)malloc(size) + size;
    __asm__("movl %0, %%esp\n" :: "r"(p) );//开栈
	scanf("%d",&n);
	for (int i=1; i<n; ++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		a[++tt].w=y;
	  	a[tt].xp=h[x];
	  	h[x]=tt;
	  	a[++tt].w=x;
	  	a[tt].xp=h[y];
	  	h[y]=tt;
	}
	dfs(1,0);//找出最远的点
	ans=0;
	dfs(k,0);//求直径
	printf("%d",(ans+1)/2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值