woc,这题就这么A了?(不敢相信)
题意:定义树核为树上最长链上的一段(长度不超过s)(也可以是一个点)
定义偏心距为到树核最远的距离,求最小偏心距
woc纯暴力居然过了
Floyd+爆搜
先找到最长链(可能不只一条)
枚举起点终点,暴力找最远距离
一遍过666
n<=300#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;#define olinr return#define love_nmr 0
int f[350][350];
int n;
int s;
int maxn;
int fa[350];
bool flag;
bool vis[350];
int ans=0x7fffffff;
vector<int>G[350];
int tot;
inline void Floyd()
{
for(int i=1;i<=n;i++)
f[i][i]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
f[j][k]=min(f[j][i]+f[i][k],f[j][k]);
}
inline void dfs(int x,int goal,int fat)
{
if(x==goal)
{
flag=true;
fa[x]=fat;
return;
}
int siz=G[x].size();
for(int i=0;i<siz;i++)
{
int go=G[x][i];
if(go!=fat)
dfs(go,goal,x);
if(flag)
{
fa[x]=fat;
return;
}
}
}
inline void dfss(int x,int dis,int fa)
{
tot=max(tot,dis);
if(dis>=ans) return;
int siz=G[x].size();
for(int i=0;i<siz;i++)
{
int go=G[x][i];
if(!vis[go]&&go!=fa)
dfss(go,dis+f[x][go],x);
}
}
inline void cl(int x,int y)
{
memset(fa,0,sizeof fa);
flag=0;
dfs(x,y,0);
int start=y;
while(5201314)
{
tot=0;
memset(vis,0,sizeof vis);
int end=start;
vis[end]=true;
int dis=0;
while(1314520)
{
if(!fa[end]) break;
if(dis+f[end][fa[end]]>s) break;
dis+=f[end][fa[end]];
end=fa[end];
vis[end]=true;
}
if(start==end)
{
for(int i=1;i<=n;i++)
tot=max(tot,f[end][i]);
}
else
{
int teme=start;
while(teme)
{
dfss(teme,0,0);
if(teme==end) break;
teme=fa[teme];
}
}
ans=min(ans,tot);
start=fa[start];
if(!start)break;
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>s;
memset(f,0x3f,sizeof f);
for(int a,b,c,i=1;i<n;i++)
{
cin>>a>>b>>c;
f[a][b]=f[b][a]=c;
G[a].push_back(b);
G[b].push_back(a);
}
Floyd();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
maxn=max(maxn,f[i][j]);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(f[i][j]==maxn)
cl(i,j);
cout<<ans<<endl;olinr love_nmr;
} ----olinr
|