基础算法学习---树的dfs

模板

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 100010,M = N * 2;

//h是N个单链表的头节点
//ne是单链表的ne数组
//e是单个节点的值
//idx是当前可用的下标
//st是检查点有无走过
int e[M],ne[M],h[N];
int n,idx = 0;
bool st[N];

//单向联通
void add(int a,int b){
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx ++;
}

//深搜,遍历每一个点
void dfs(int u){
    st[u] = true;

    for(int i = h[u];i != -1;i = ne[i]){
        int j = e[i];
        if(!st[j]) dfs(j);
    }
}

int main(){
    cin >> n;

//点的状态初始化
    memset(h,-1,sizeof h);

    while(n --){
        int a,b;
        cin >> a >> b;

        add(a,b);
    }

    dfs(0);
}
树的重心
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 100010,M = N * 2;

int e[M],ne[M],h[N];
int idx = 0;
int st[M];
int n;

int ans = N;

void add(int a,int b){
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx ++;
}

int dfs(int u){
    st[u] = 1;      //当前点走过

    int sum = 1,res = 0;        //sum是该点的节点数,res是连通块内点的数量

    //遍历一条树枝
    for(int i = h[u];i != -1;i = ne[i]){
        int j = e[i];           //取出子节点下标
        if(!st[j]){
            int t = dfs(j);     //算出子节点的节点数
            sum += t;           
            res = max(res,t);
        }
    }

    res = max(res,n - sum);     //取连通块节点最大值
    ans = min(ans,res);

    return sum;
}

int main(){
    cin >> n;

    memset(h,-1,sizeof h);         //点的状态初始化

    for(int i = 1;i < n;i ++){
        int a,b;
        cin >> a >> b;

        add(a,b),add(b,a);         //无向图所以要双向加边
    }

    dfs(1);

    cout << ans;
}
posted @ 2021-07-20 14:47  Xuuxxi  阅读(36)  评论(0编辑  收藏  举报