zoukankan      html  css  js  c++  java
  • 树基础4.28

    ,1、常见的输入树的情况

    (1)输入每个结点的父亲编号

    //输入每个点的父亲 
    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    #define N 10010
    vector<int>vec[N];
    int x,n,vis[N];
    void dfs(int x){
        vis[x]=1;
        for(int i=0;i<vec[x].size();i++){
            if(!vis[vec[x][i]])dfs(vec[x][i]);
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=2;i<=n;i++){
            scanf("%d",&x);
            vec[x].push_back(i);//记录每个点的儿子,x点的儿子是第i个点 
        }
        dfs(1);
        return 0;
    }

    (2)输入n-1条边的信息 不定根

    //给出n-1条边的信息 遍历树 
    #include<iostream>
    #include<vector>
    #include<cstdio>
    #include<bits/stdc++.h>
    using namespace std;
    #define N 10010
    vector<int>vec[N];
    int dad[N],x,y,n;
    void dfs(int x)
    {
        for(int i=0;i<vec[x].size();i++){//遍历和它相连的边 
            if(dad[x]!=vec[x][i]){
                dad[vec[x][i]]=x;
                dfs(vec[x][i]);//进行深搜; 
            }
        }
    }
    int main() 
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x,&y);//储存双向边 
            vec[x].push_back(y);
            vec[y].push_back(x);
        }
        dfs(1);
        return 0;
    }

    2、求树的直径
    树上最长的简单路径为树的直径

    在树上任选一点u,以u为根进行一遍dfs,求距离u最远的点s,以s为根进行一遍dfs,找到距离s最远的点t,点s和点t之间的路径为树的直径;

    //求树的直径 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<bits/stdc++.h>
    using namespace std;
    #define N 10010 
    vector<int>vec[N];
    int x,y,n,t,s,dis[N]; 
    void dfs(int x)
    {
        for(int i=0;i<vec[x].size();i++){
            if(!dis[vec[x][i]]){//没有访问过 
                dis[vec[x][i]]=dis[x]+1;//dis[vec[x][i]]到x的距离为dis[x]的距离+1 
                dfs(vec[x][i]);
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            vec[x].push_back(y);
            vec[y].push_back(x);
        }
        dfs(1);//随便找一个点  
        for(int i=1;i<=n;i++){
            if(dis[i]>dis[t])t=i;//找出和它距离最大的那个点 
        }
        memset(dis,0,sizeof(dis));//一定要清0 
        dfs(t);//再找距离t最大的点 
        for(int i=1;i<=n;i++){
            if(dis[i]>dis[s])
            s=i;
        }
        printf("%d",dis[s]);//这个点到t点的距离为树的直径 
        return 0;
    }

    3、找到一个点,其所有的子树中最大的子树结点数最少,这个点就是这个树的重心;树的总点数为偶数时,可能会有两个重心。

    先随意确定一个根,之后通过一遍dfs将所有子树的大小求出来。

    如果有一个点i满足2*size i >=n,并且它的儿子都满足2*size son i <=n,那么这个点就是这个树的重心;

    //求树的重心 
    #include<iostream>
    #include<cstdio>
    #include<bits/stdc++.h>
    using namespace std;
    #define N 10010
    vector<int>vec[N];
    int ans,x,y,n,sizd[N],dad[N];
    void dfs(int x)
    {
        size[x]=1;
        for(int i=0;i<vec[x].size();i++)
        {
            if(dad[x]!=vec[x][i])
            {
                dad[vec[x][i]]=x;
                dfs(vec[x][i]);
                size[x]+=size[vec[x][i]];//它本身的个数加上它儿子结点的个数 
            }
        }
        if(size[x]*2>=n&&!ans)//满足重心的条件 
        {
            ans=x;
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            vec[x].push_back(y);//建边 
            vec[y].push_back(x);
        }
        dfs(1);//搜每个点子树结点的个数 
        printf("%d",ans);
        return 0;
    } 
  • 相关阅读:
    CAP概述与技术选型
    maven基础命令
    那就从头开始吧,哈哈。
    react 小细节
    二分查找法,折半查找原理
    心态很重要
    apache 软件基金会分发目录。
    jquery的基础知识复习()
    jquery的基础知识复习(基础选择器,属性选择器,层级选择器)
    CPP函数类型转换
  • 原文地址:https://www.cnblogs.com/zzyh/p/6785006.html
Copyright © 2011-2022 走看看