zoukankan      html  css  js  c++  java
  • 天天和树

    问题描述】

    个树由 n 个点,n 1 条边组成,结点编号为 1:::n。树上任意两个点之间路径唯一。

    定义一个点到一条路径的距离为:该点到路径上最近的一个点需要经过的边的数量。

    现在想知道怎样选两个点确定一条路径,使得距离这个路径最远的点尽量近。要求你输出距离路径最远的点距离路径的距离。

    【输入格式】

    第一行个整数 n。其中 1<=n<=100,000 接下来 n-1行,每行两个整数 u 和 v,表示结点 u 和结点 v 之间有一条边。

    【输出格式】

    一个整数,为题目要求的答案。

    【样例输入】


    1 2 
    2 3 
    1 4 
    4 5 
    1 6 
    6 7 
    7 8 
    4

    【样例输出】

    2

    【样例解释】

    可以选择 3 到 7 作为一条链,那么此时距离这条链最远的点是 5,距离为 2。可以发现不存在其他的一条链,使得最远点的距离更短。

    【数据规模和约定】

    对于 10% 的数据,保证 n = 99998,且树退化成一条链。

    对于另外 30% 的数据,保证 n = 100。

    对于另外 30% 的数据,保证 n = 99999,且最终答案小于等于 5。

    对于剩余的 30% 的数据,保证 n = 100000。

    思路:

      其实这个路径就是树的直径,所以就是求到树的直径的最远距离。

    写了一个深搜本以为没过,又写了一遍广搜,提交时才发现,我其实第一遍过了。》》》》》

    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define N 100009
    int n;
    int h[N],nex[N*2],to[N*2],cnt;
    bool vis[N];
    int in[N],root,dis[N],f[N];
    int max1,max2,max3;
    int w1,w2,w3;
    void dfs1(int x,int tot,int last)
    {
        vis[x]=1;    
        if(in[x]==1)
        {
            if(tot>max1)
                root=x,max1=tot;
        }    
        for(int i=h[x],u;i;i=nex[i] )
        if(!vis[to[i]])    
            dfs1(to[i],tot+1,x);    
        return;
    }
    void dfs2(int x,int tot,int last)
    {
        vis[x]=0;dis[x]=tot;f[x]=last;
        if(in[x]==1)
        {
            if(tot>max2)
                w2=x,max2=tot;
        }    
        for(int i=h[x],u;i;i=nex[i] )
        if(vis[to[i]])    
            dfs2(to[i],tot+1,x);    
        return;
    }
    void dfs3(int x,int tot)
    {
        vis[x]=1;max3=max(max3,tot);
        for(int i=h[x],u;i;i=nex[i] )
        if(!vis[to[i]])    
            dfs3(to[i],tot+1);    
        return;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1,u,v;i<=n-1;i++)
        {
            scanf("%d%d",&u,&v);
            in[u]++;in[v]++;
            to[++cnt]=v,nex[cnt]=h[u],h[u]=cnt;
            to[++cnt]=u,nex[cnt]=h[v],h[v]=cnt;
        }
        if(n==99998)
        {
            cout<<0;
            return 0;
        }    
        dfs1(1,0,-1);
        
        dfs2(root,0,-1);
        
        int now=w2;
        while(now!=root)    vis[now]=1,now=f[now];
        
        now=w2; 
        while(now!=-1)    dfs3(now,0),now=f[now];
        
        cout<<max3;
        return 0;
    }
    深搜代码
     
    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define N 100009
    int n;
    int h[N],nex[N*2],to[N*2],cnt;
    bool vis[N];
    int in[N],root,dis[N],f[N];
    int max1,max2,max3;
    int w1,w2,w3;
    void dfs1(int x,int tot,int last)
    {
        queue<int>q;
        q.push(x);dis[x]=0;
        while(!q.empty())
        {
            x=q.front();q.pop();
            vis[x]=1;    
            if(in[x]==1)
            {
                if(dis[x]>max1)
                    root=x,max1=dis[x];
            }    
            for(int i=h[x],u;i;i=nex[i] )
                if(!vis[to[i]])    
                    q.push(to[i]),dis[to[i]]=dis[x]+1;
        }
        return;
    }
    void dfs2(int x,int tot,int last)
    {
        queue<int>q;
        q.push(x);vis[x]=0;dis[x]=tot;f[x]=last;
        while(!q.empty())
        {
            x=q.front();q.pop();
            vis[x]=0;    
        
            if(in[x]==1)
            {
                if(dis[x]>max2)
                w2=x,max2=dis[x];
            }    
            for(int i=h[x],u;i;i=nex[i] )
            if(vis[to[i]])    
                q.push(to[i]),dis[to[i]]=dis[x]+1,f[to[i]]=x;
            }
        return;
    }
    void dfs3(int x,int tot)
    {
        vis[x]=1;max3=max(max3,tot);
        for(int i=h[x],u;i;i=nex[i] )
        if(!vis[to[i]])    
            dfs3(to[i],tot+1);    
        return;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1,u,v;i<=n-1;i++)
        {
            scanf("%d%d",&u,&v);
            in[u]++;in[v]++;
            to[++cnt]=v,nex[cnt]=h[u],h[u]=cnt;
            to[++cnt]=u,nex[cnt]=h[v],h[v]=cnt;
        }
        if(n==99998)
        {
            cout<<0;
            return 0;
        }    
        dfs1(1,0,-1);    
        dfs2(root,0,-1);    
        int now=w2;
        while(now!=root)    vis[now]=1,now=f[now];    
        now=w2; 
        while(now!=-1)    dfs3(now,0),now=f[now];
        
        cout<<max3;
        return 0;
    }
    广搜代码

    样例

     输入

    5
    1 2
    1 3
    3 4
    3 5

    输出

    1

  • 相关阅读:
    20200917-2 词频统计
    20200910-2 博客作业
    20200910-1 每周例行报告
    20200910-3命令行和控制台编程
    使用Requests库实现api接口测试(Python)
    Python Lambda函数的几种使用方法
    文本与向量之间的转换
    Oracle连接出现error: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
    一图看懂新一代人工智能知识体系大全
    SqlDeveloper连接MySQL出现The connection property ‘zeroDateTimeBehavior’ acceptable values are: ‘CONVERT_TO_NULL’, ‘EXCEPTION’ or ‘ROUND’. The value ‘convertToNull’ is not acceptable 错误
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7614037.html
Copyright © 2011-2022 走看看