GYM 101522B. Bacteria Experiment

GYM 101522B. Bacteria Experiment

   题目大意是:给定一个树形图,n个节点,n-1条边,每一个小时内,可以把两个有相同父节点的并且不相连的两个节点连接,要经过多少个小时才可以把整个图变成全连通图。

   解题的方法肯定不是模拟,就时间复杂度就接受不了模拟,所以要有技巧。我们可以想象,要全连通,那么该图中相距最远的两个点一定也要连接起来,并且它们是花费时间最长的两个点,所以我们只需要求出这最远的两个点需要多少时间连接就是全连通的时间,根据连接的方法,每次只能相同父节点的两个点相连,例如一条最长路:(1,2,3,4,5,6,7,8,9),第一步连接(1,3),(2,4),(3,5)…,(7,9),这个时候第二步连接(1,5)(2,6)(3,7)(4,8),(5,9),第三步的时候(1,9).1号和9号就连接起来了,每一步的跨度逐渐变大,增长的速度是 2n 2 n 。所以我们找到最长路的长度,再和 2n 2 n 比较,向上取整。就是需要的时间。

   求树形结构中最长路的方法就是利用两次BFS,第一次BFS从任意点出发,第二次BFS从第一次求得的最远点出发。第一次求得的最远点一定是在最长路的路径上。所以再一次BFS求得的长度就是最长路径。

#include <bits/stdc++.h>

using namespace std;
const int maxn = 500000+5;
vector<int> edge[maxn];
int color[maxn],w[maxn],fuck;
void bfs(int s)
{
    queue<int> q;
    memset(w,0,sizeof(w));
    memset(color,0,sizeof(color));
    color[s] = 1;
    w[s] = 0;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        fuck = u;
        int len = edge[u].size();
        for(int i=0; i<len; i++)
        {
            if(!color[edge[u][i]])
            {
                q.push(edge[u][i]);
                color[edge[u][i]]=1;
                w[edge[u][i]] = w[u]+1;
            }
        }
    }
}
long long num[100];
int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    num[0]=1;
    for(int i=1; i<61; i++)
    {
        num[i] = num[i-1]*2;
    }
    scanf("%d",&n);
    int u,v;
    if(n==2)
    {
        printf("0\n");
        return 0;
    }
    for(int i=0; i<n-1; i++)
    {
        scanf("%d%d",&u,&v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    bfs(u);
    bfs(fuck);
    int ans = 1;
    for(int i=2; i<61; i++)
    {
        if(w[fuck]<=num[i] && w[fuck]>num[i-1])
        {
            ans = i;
            break;
        }
    }
    printf("%d\n",ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值