这个题感觉叉姐讲的灰常好,我就不献丑了
偷偷放上链接
具体代码就是两遍DFS
感觉也没什么好讲的样子?
那就看代码吧恩(点头)
-------------------------我是代码的昏割线-------------------
#include<bits/stdc++.h>
using namespace std;
const int maxn = 112345;
vector<int> edge[maxn];
void init(int n){
for(int i=0;i<=n;i++)
edge[i].resize(0);
}
void Link(int st,int ed){
edge[st].push_back(ed);
edge[ed].push_back(st);
}
bool newt[maxn];
bool vis[maxn];
bool dfsg(int st){
vis[st]=true;
for(auto &x:edge[st]){
if(vis[x]==false){
vis[x]=true;
if(dfsg(x)){
newt[st]=true;
}
}
}
return newt[st];
}
int dis[maxn];
void dfsnd(int st,int d){
dis[st]=d;
for(auto &x:edge[st]){
if(newt[x]==true && dis[x]==-1){
dfsnd(x,d+1);
}
}
}
int disa[maxn];
int disb[maxn];
void dfs(int st,int d,int *dis){
dis[st]=d;
for(auto & x : edge[st]){
if(dis[x]==-1)
dfs(x,d+1,dis);
}
}
int main(){
int n,m,d;
while(~scanf("%d %d %d",&n,&m,&d)){
memset(newt,0,sizeof(newt));
init(n);
int st;
while(m--){
scanf("%d",&st);
newt[st]=true;
}
int u,v;
for(int i=1;i<n;i++){
scanf("%d %d",&u,&v);
Link(u,v);
}
memset(vis,0,sizeof(vis));
dfsg(st);
memset(dis,-1,sizeof(dis));
dfsnd(st,0);
int sta = st;
for(int i=1;i<=n;i++){
if(dis[i] > dis[sta])
sta = i;
}
memset(dis,-1,sizeof(dis));
dfsnd(sta,0);
int stb = sta;
for(int i=1;i<=n;i++){
if(dis[i] > dis[stb])
stb = i;
}
memset(disa,-1,sizeof(disa));
memset(disb,-1,sizeof(disb));
dfs(sta,0,disa);
dfs(stb,0,disb);
int ans=0;
for(int i=1;i<=n;i++){
if(max(disa[i],disb[i]) <=d)
ans++;
}
printf("%d\n",ans);
}
return 0;
}

本文介绍了一种使用两遍深度优先搜索(DFS)解决特定图论问题的方法。通过两次DFS分别找到图中两个关键节点,并计算从这两个节点出发到其他所有节点的距离,最终确定满足条件的节点数量。
618

被折叠的 条评论
为什么被折叠?



