暑 假 队 测 Round #1
暑假第一次队测就被吊起来打了。。
\(50+37+100=187pts\)
T1国王游戏
T2没找到,题目大意
T3Computer Network
T1:贪心
是个很经典的邻项微扰,可惜不会打高精(wtcl)...
T2:DFS
n和m的数据范围很明显是在暗示dfs+剪枝了,
我这个睿智还是码了个01背包。。。
37滚粗。
T3:Tree Dp
唯一一个AC的题
口胡做法:
二次扫描+换根,结点可以用离父亲结点最远与次远的值来更新
这取决与结点是否位于父亲结点的最长链上。
感觉最近dp水平进步还挺快
然后因为一些sb错误改了很久,幸好最后de出来了。
T3Code:
#include<bits/stdc++.h>
using namespace std;
const int N=3e4+10;
int n,pre[N],now[N],to[N],tot;
int d[N][3],f[N],ins[N];
int lst[N];
void add(int x,int y){
pre[++tot]=now[x];
to[tot]=y;now[x]=tot;
}
void dfs(int u,int fa){
for(int i=now[u];i;i=pre[i]){
int v=to[i];
if(v==fa)continue;
dfs(v,u);
if(d[u][1]==d[u][2]&&d[u][1]==0)
d[u][1]=d[u][2]=1;
if(d[u][1]<=d[v][1]+1){
swap(d[u][1],d[u][2]);
d[u][1]=d[v][1]+1;
ins[lst[u]]=0;
ins[v]=1;
lst[u]=v;
}
else d[u][2]=max(d[u][2],d[v][1]+1);
}
}
void DFS(int u,int fa){
for(int i=now[u];i;i=pre[i]){
int v=to[i];
if(v==fa)continue;
f[v]=max(f[v],f[u]+1);
if(ins[v]==1)
f[v]=max(f[v],d[u][2]+1);
else f[v]=max(f[v],d[u][1]+1);
DFS(v,u);
}
}
int main(){
//freopen("tree.in","r",stdin);
//freopen("tree.out","w",stdout);
scanf("%d",&n);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1,0);
DFS(1,0);
for(int i=1;i<=n;i++)
printf("%d\n",max(f[i],d[i][1]));
return 0;
}