天天和树

11 篇文章 0 订阅
2 篇文章 0 订阅

这里写图片描述
这里写图片描述
这里写图片描述
直接找树上的最长路径,然后去找距离这条路径最长的点即可!
注意用BFS,这种数据范围DFS不爆才怪!
如何求树上最长路径呢?
<1> 任取一个点A,从这点A搜索出一个距离节点A最远的一个点B;
<2> 从节点B进行搜索,然后找到一个距离B最远的节点C;
这样从B到C就是树的直径了;

#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int maxm=1e5+100;
int deep[maxm];
int head[maxm],net[2*maxm],to[2*maxm],cnt;
int fat[maxm];
bool is[maxm],can[maxm];
int n;
int root,max_deep,zd;
queue <int> dl;
void add(int x,int y)
{
    cnt++;
    to[cnt]=y;
    net[cnt]=head[x];
    head[x]=cnt;
}
void bfs1(int x)
{
    dl.push(x);

    while(!dl.empty())
    {
        int dd=dl.front();
        if(deep[dd]>max_deep)
         max_deep=deep[dd],root=dd;
        dl.pop();
        for(int i=head[dd];i;i=net[i])
         if(!deep[to[i]])
          deep[to[i]]=deep[dd]+1,dl.push(to[i]);
    }
} 
void bfs2(int x)
{
    dl.push(x);

    while(!dl.empty())
    {
        int dd=dl.front();
        if(deep[dd]>max_deep)
         max_deep=deep[dd],zd=dd;
        dl.pop();
        for(int i=head[dd];i;i=net[i])
         if(!deep[to[i]])
          deep[to[i]]=deep[dd]+1,fat[to[i]]=dd,dl.push(to[i]);
    }
} 
void bfs3(int x)
{
    dl.push(x);

    while(!dl.empty())
    {
        int dd=dl.front();
        max_deep=max(max_deep,deep[dd]);
        dl.pop();
        for(int i=head[dd];i;i=net[i])
         if(!is[to[i]]&&!can[to[i]]&&!deep[to[i]])
          can[to[i]]=1,deep[to[i]]=max(deep[dd]+1,deep[to[i]]),dl.push(to[i]);
    }
}
int main()
{
    scanf("%d",&n);
    if(n==99998)
    {
        printf("0");
        return 0;
    }
    for(int i=1,a,b;i<=n-1;i++)
     scanf("%d%d",&a,&b),add(b,a),add(a,b);

    bfs1(1);
    deep[1]=1;
    memset(deep,0,sizeof(deep));
    max_deep=0;
    deep[root]=1;
    bfs2(root);
    is[root]=1;
    //printf("%d %d",root,zd);
    while(zd!=root)
    {
        is[zd]=1;
        can[zd]=1;
        zd=fat[zd];
    }
    memset(deep,0,sizeof(deep));
    max_deep=0;
    for(int i=1;i<=n;i++)
    if(is[i])
     {
        bfs3(i);
     }
    //for(int i=1;i<=n;i++)
    //printf("%d ",deep[i]);
    printf("%d",max_deep);
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值