他解:拓扑排序,直接考虑
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+50;
typedef long long ll;
int n,k;
struct edge{
int to,nex;
}e[N<<1];
int uu,vv;
int deg[N];
int head[N];
int num=0;
void add(int u,int v)
{
e[num]=(edge){v,head[u]};
head[u]=num++;
deg[v]++;
}
queue<int>q;
int dep[N];
int ans;
void topu()
{
int now,too;
while(!q.empty())
{
now=q.front();
q.pop();
for(int i=head[now];i!=-1;i=e[i].nex)
{
too=e[i].to;
if(--deg[too]!=1)
continue;
q.push(too);
k--;
dep[too]=dep[now]+1;
ans=max(dep[too],ans);
if(k<=0)
return ;
}
}
}
int main ()
{
cin>>n>>k;
k=n-k;
memset(head,-1,sizeof(head));
for(int i=1;i<n;++i)
{
cin>>uu>>vv;
add(uu,vv);
add(vv,uu);
}
for(int i=1;i<=n;++i)
{
if(deg[i]==1)
{
q.push(i);
k--;
dep[i]=1;
}
}
if(k<=0)
{
cout<<"1";
}
else {
ans=1;
topu();
cout<<ans;
}
return 0;
}
正解: 有于要找的是k个直接连通的城市,所以先找树的重心然后根据最深可到距离-当前距离排序取(回溯)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+50;
typedef long long ll;
int n,k;
struct edge{
int to,nex;
}e[N<<1];
int uu,vv;
int head[N];
int num=0;
int dep[N];
int f[N];
int maxdep[N];
int ans[N];
void add(int u,int v)
{
e[num]=(edge){v,head[u]};
head[u]=num++;
}
void dfs1(int x,int fa)
{
int too;
for(int i=head[x];i!=-1;i=e[i].nex)
{
too=e[i].to;
if(too==fa)
continue;
dep[too]=dep[x]+1;
dfs1(too,x);
}
}
void dfs2(int x,int fa)
{
int too;
for(int i=head[x];i!=-1;i=e[i].nex)
{
too=e[i].to;
if(too==fa)
continue;
f[too]=x;
dep[too]=dep[x]+1;
dfs2(too,x);
}
}
void dfs(int x,int fa)
{
maxdep[x]=dep[x]=dep[fa]+1;
int too;
for(int i=head[x];i!=-1;i=e[i].nex)
{
too=e[i].to;
if(too==fa)
continue;
dfs(too,x);
maxdep[x]=max(maxdep[too],maxdep[x]);
}
}
int main ()
{
cin>>n>>k;
memset(head,-1,sizeof(head));
for(int i=1;i<n;++i)
{
cin>>uu>>vv;
add(uu,vv);
add(vv,uu);
}
dfs1(1,0);
int numl=1,l=dep[1];
for(int i=2;i<=n;++i)
{
if(l<dep[i])
{
l=dep[i];
numl=i;
}
}
memset(dep,0,sizeof(dep));
dfs2(numl,0);
numl=1,l=dep[1];
for(int i=2;i<=n;++i)
{
if(l<dep[i])
{
l=dep[i];
numl=i;
}
}
int kk=numl;
for(int i=1;i<=(dep[numl]+1)/2;++i)
{
kk=f[kk];
}
memset(dep,0,sizeof(dep));
dfs(kk,0);
for(int i=1;i<=n;++i)
{
ans[i]=maxdep[i]-dep[i];
}
sort(ans+1,ans+1+n);
cout<<ans[n-k]+1;
return 0;
}