机器选择
题目大意:
有一个树状的图,要求安一个点,使这个点到最远的点的距离最小
原题:
题目描述
自从省队NOI赛前集训在scz举行之后,一个名叫cs1.6.exe的文件开始在机房广泛使用起来。每天大家都要找神犇小X借移动硬盘,考里面的这个文件。
由于机房里需要考这个文件的人太多了,每天都要花一段时间一个人一个人的去拷贝。小T觉得这实在是太麻烦了,就想找一个一劳永逸的方法。
小T调查了一下,机房有n台机器,且有局域网,所有机器通过一些网线连接起来,其整个布局是一个树形结构,即任意两台机器间都有且仅有一条路径。小T想在其中某一台机器上储存这个文件,需要的同学就可以直接通过局域网来下载这个文件。
网络上信息传输是需要时间的,我们定义两台机器间数据传输的时间为连接这两台机器的路径所包含的网线数量。虽然机房里通过局域网传个文件是很快的,但对于急不可耐的同学们来说,一分一秒都是宝贵的,文件传输越快越好。所以小T要选择一台机器存储文件,使得所有机器下载这个文件需要的总时间(即最后一台机器完成下载的时间)尽可能短。
现在,你需要给出这个最短时间,以便让小T看看他的决策是否最优。
输入
第1行:一个整数n。
第2n行:两个整数u、v,即u、v两台机器间有一条网线连接。机器从1n编号。
输入数据保证是一个连通的树型结构。
输出
1行一个整数,即最短的时间。
输入样例
5
3 2
2 1
5 2
2 4
输出样例
1
说明
【数据范围】
对于30%的数据,n≤100;
对于50%的数据,n≤1000;
对于100%的数据,2≤n≤100000。
解题思路:
直接暴力搜可以拿50分
想要拿100分就要先求出这棵树的直径,然后除以2就可以了
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int n,m,x,y,w,k,ans,p[100005],head[100005];
struct rec
{int to,next;
}a[200005];
void dfs(int dep,int s)
{p[dep]=1;//记录if (s>ans) ans=s,k=dep;//代替for (int i=head[dep];i;i=a[i].next)if (!p[a[i].to]) dfs(a[i].to,s+1);//搜下去p[dep]=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){scanf("%d %d",&x,&y);a[++w].to=y;//存线路a[w].next=head[x];head[x]=w;a[++w].to=x;a[w].next=head[y];head[y]=w;}dfs(1,0);ans=0;dfs(k,0);//求直径printf("%d",(ans+1)/2);//除以2(加1是因为他是由0开始的)
}