GYM 101522B. Bacteria Experiment

B. Bacteria Experiment

time limit per test

memory limit per test

input

output

A year after his bacteria experiment, Jason decided to perform another experiment on a new bacteria specie which evolves in a special way. The initial form of the bacteria can be considered as an undirected tree with N nodes in terms of graph theory. Every hour, an edge (x, y) is built if there exists a node z such that, in the previous hour, there exists edge (x, z) and edge (y, z), but not edge (x, y). The bacteria keep evolving until no more edges can be formed.

The following graph shows a type of bacteria which requires 2 hours to fully evolve:

img

As it may take months if not years for the bacteria to evolve to its ultimate form, it is impossible for Jason to stay at the laboratory to observe the change of the bacteria throughout the entire process. Therefore, he wants you to calculate the time required for the bacteria to fully evolve, so that he can just get back to the laboratory on time.

Input

The first line contains an integer N. (2 ≤ N ≤ 5 × 105)

The next N - 1 line each contains two integers u and v, which means there exists an edge between node u and v. (1 ≤ u, v ≤ N)

The given graph is guaranteed to be a valid tree.

Output

Output an integer, the time (in hours) required for the bacteria to fully evolve.

Example

input

6
1 5
5 3
5 6
6 2
6 4

output

2

题意

​ 给出一张图,每过一个小时相同父节点的子节点可以互相连接,问最多几个小时可以变成完成图。

解题思路

​ 找出这个图的最长的路。由于节点之间可以互相传递,例如1-2-3-4-5,第一个小时1和3连、2和4连、3和5连,第二个小时就可以1和5连,只要头和尾连接成功就结束。这样看下来,时间就是这条最长路的长度离的最近的2^n,而且向上取,n即为时间。

​ 关于求这个图的最长路,先以任意点开始bfs,最后到达的点一定是最长路的一个端点,然后再以这个点开始进行bfs,可以得到最长路的长度。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
#define inf 0x3f3f3f3f

struct node
{
    int x,step;
    node() {}
    node(int a,int b):x(a),step(b) {}
} tmp;
struct edge
{
    int to,next;
} edges[maxn*2];
int head[maxn],cnt,n;
int vis[maxn];

void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}
void addedges(int u,int v)
{
    edges[cnt].to=v;
    edges[cnt].next=head[u];
    head[u]=cnt++;
}
void bfs(int r)
{
    memset(vis,0,sizeof(vis));
    queue<node> q;
    q.push(node(r,0));
    vis[r]=1;
    while(!q.empty())
    {
        node x=q.front();
        q.pop();
        tmp=x;
        for(int i=head[x.x]; ~i; i=edges[i].next)
        {
            if(vis[edges[i].to]) continue;
            vis[edges[i].to]=1;
            q.push(node(edges[i].to,x.step+1));
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d",&n);
    if(n==2)
    {
        printf("0\n");
        return 0;
    }
    init();
    int a,b;
    for(int i=1; i<n; i++)
    {
        scanf("%d%d",&a,&b);
        addedges(a,b);
        addedges(b,a);
    }
    bfs(a);
    bfs(tmp.x);
    long long arr[60];
    arr[1]=2;
    for(int i=2; i<60; i++)
        arr[i]=2*arr[i-1];
    int ans=1;
    for(int i=2; i<60; i++)
        if(tmp.step>arr[i-1]&&tmp.step<=arr[i])
        {
            ans=i;
            break;
        }
    printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/RefrainLi/p/8861409.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值