题目描述
链接:https://nanti.jisuanke.com/t/44347
题目还是有点难读懂的。但实际上就是求树的直径,算出不在直径上的路径的个数
思路分析
貌似是第一次接触树的直径。查了下方法,有三种,分别是:
两次bfs
两次dfs
树形dp
三种我都写了一次,感觉还是比较好掌握的的,以后加以熟练就是了。
贴个大佬博客:https://blog.csdn.net/forever_dreams/article/details/81051578
AC代码
树形dp
#include <iostream>
#include <cstring>
#define MEM(a) memset(a,0,sizeof(a))
using namespace std;
struct Edge{
int to;
int next;
};
const int maxn=10005;
int cnt=0;//
int head[maxn];//
Edge e[maxn<<1];//
int f1[maxn],f2[maxn];//
int ans=0;//
void add(int x,int y){
e[cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt++;
}
void dp(int v,int fa){
for(int i=head[v];i!=-1;i=e[i].next){
int u=e[i].to;
if(u==fa) continue;
dp(u,v);
int tmp=f1[u]+1;
if(tmp>f1[v]){
f2[v]=f1[v];
f1[v]=tmp;
}
else if(tmp>f2[v]){
f2[v]=tmp;
}
}
ans=max(ans,f1[v]+f2[v]);
}
int main()
{
int kase;
cin>>kase;
while(kase--){
ans=0;
cnt=0;
MEM(f1),MEM(f2),MEM(e);
for(int i=0;i<maxn;i++) head[i]=-1;
int n;
cin>>n;
for(int i=1;i<n;i++){
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
dp(1,-1);
cout<<n-1-ans<<endl;
}
return 0;
}
dfs
#include <iostream>
#include <cstring>
#define MEM(a) memset(a,0,sizeof(a))
using namespace std;
const int maxn=10005;
struct Edge{
int to;
int next;
}e[maxn<<1];//
int mo,md;//
int head[maxn]={0};
int vis[maxn]={0};//
int cnt=0;//
void add(int x,int y){
e[cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt++;
}
void dfs(int u,int k){
if(k>md){
md=k;
mo=u;
}
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
if(vis[v]) continue;
vis[v]=1;
dfs(v,k+1);
vis[v]=0;
}
}
int main()
{
int kase;
cin>>kase;
while(kase--){
MEM(e);
mo=0;
md=0;
MEM(vis);
cnt=0;
int n;
cin>>n;
for(int i=0;i<=n;i++) head[i]=-1;
for(int i=1;i<n;i++){
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
vis[1]=1;
dfs(1,0);
md=0;
MEM(vis);
vis[mo]=1;
dfs(mo,0);
cout<<n-1-md<<endl;
}
return 0;
}
bfs
#include <iostream>
#include <queue>
#include <cstring>
#define MEM(a) memset(a,0,sizeof(a))
using namespace std;
struct Edge{
int to;
int next;
};
int mo=0,md;
const int maxn=10005;
int cnt=0;//
int head[maxn];//
Edge e[maxn<<1];//
int vis[maxn];//
void add(int x,int y){
e[cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt++;
}
struct node{
int pos;
int step;
};
void bfs(int sx){
queue<node> que;
node start={sx,0};
vis[sx]=1;
que.push(start);
while(!que.empty()){
node a=que.front();
que.pop();
int v=a.pos;
int ns=a.step;
if(ns>md){
md=ns;
mo=v;
}
for(int i=head[v];i!=-1;i=e[i].next){
if(vis[e[i].to]) continue;
vis[e[i].to]=1;
int dx=ns+1;
node af={e[i].to,dx};
que.push(af);
}
}
}
int main()
{
int kase;
cin>>kase;
while(kase--){
MEM(vis);
MEM(e);
cnt=0;
md=0;
mo=0;
for(int i=0;i<maxn;i++) head[i]=-1;
int n;
cin>>n;
for(int i=1;i<n;i++){
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
bfs(1);
MEM(vis);
md=0;
bfs(mo);
cout<<n-1-md<<endl;
}
return 0;
}