算法入门-小G有一个大树

小G有一个大树

https://ac.nowcoder.com/acm/problem/15033

题意

  • 对于一棵树,我们希望找到一个点,使得删除这个点之后,最大子树的结点数最小
  • 以边的形式输入,输出被删除的点的编号和删除后最大子树的结点数

思路

  • 考虑用无根树描述,对于树的某一个结点,删掉后,整棵树变为两部分
    • 这个结点的父亲所属的树
    • 这个结点的若干子树
  • 故另表示删除这个点后最大子树结点数,表示这个点除了父亲以外的子树的总结点数,则就是祖先部分的结点数
  • 得到,u是i的每一个儿子,
  • 所求答案为所有中最小的一个

代码

#include<bits/stdc++.h>
#define maxn 1024
using namespace std;
int n;
int tol[maxn],f[maxn];
vector<int> tree[maxn];
void dfs(int x,int fa){
    int tolu=-0x3f3f3f3f;
    tol[x]=1;
    for(int i=0;i<tree[x].size();i++){
        int son=tree[x][i];
        if(son==fa) continue;
        dfs(son,x);
        tol[x]+=tol[son];
        tolu=max(tolu,tol[son]);
    }
    f[x]=max(n-tol[x],tolu);
    // cout << x << ' ' << fa << ' ' << tolu << ' ' << tol[x] << endl ;
}

int main(){

    while(cin >> n){
        for(int i=0;i<maxn;i++){
            tree[i].clear();
        }
        for(int i=1;i<n;i++){
            int a,b;
            cin >> a >> b ;
            tree[a].push_back(b);
            tree[b].push_back(a);
        }
        dfs(1,0);
        int idx=0,ans=0x3f3f3f3f;
        for(int i=1;i<=n;i++){
            if(f[i]<ans){
                idx=i;
                ans=f[i];
            }
        }
        cout << idx << ' ' << ans << endl ;
    }
    return 0;
}
全部评论

相关推荐

吐泡泡的咸鱼:我也工作了几年了,也陆陆续续面试过不少人,就简历来说,第一眼学历不太够,你只能靠你的实习或者论文或者项目经历,然后你没有论文,没有含金量高的比赛和奖项,只能看实习和项目,实习来说,你写的实习经历完全不清楚你想找什么工作?行研?数据分析?且写的太少了,再看项目,这些项目先不说上过大学读过研究生的都知道很水,然后对你想找的岗位有什么帮助呢?项目和实习也完全不匹配啊,你好像在努力将你所有的经历都放在简历里想表现你的优秀,但是对于你想找的岗位来说,有什么用呢?最后只能获得岗位不匹配的评价。所以你需要明白你想要找的岗位要求是什么,是做什么的,比如产品经理,然后再看你的经历里有什么匹配的上这个岗位,或者对这个岗位以及这个岗位所在的公司有价值,再写到你的简历上
点赞 评论 收藏
分享
程序员牛肉:主要是因为小厂的资金本来就很吃紧,所以更喜欢有实习经历的同学。来了就能上手。 而大厂因为钱多,实习生一天三四百的就不算事。所以愿意培养你,在面试的时候也就不在乎你有没有实习(除非是同级别大厂的实习。) 按照你的简历来看,同质化太严重了。项目也很烂大街。 要么换项目,要么考研。 你现在选择工作的话,前景不是很好了。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务