标签:Buds 结点 16 int Global 叶子 include bud define
-
题意:一颗\(n\)个点的树,定义bud为某个点至少有一个儿子,所有儿子均为叶子结点且这个点不为根,你可以将任意一个bud和它的所有儿子移动到另外一个顶点上,可以操作任意次,问最后的叶子结点数最少是多少.
-
题解:假如我们将一个bud移到另一个叶子结点上后,bud的父亲变成了一个叶子结点,那么会发现,总叶子结点数是不变的,叶子结点想要减少,就必须满足移动后,bud的父亲不会变成一个叶子结点,很明显,如果bud的父亲是根,那么肯定满足这个条件.所以我们首先把所有bud拆了接到根结点上,那么假设此时的bud数为\(k\),此时的叶子结点数为\(n-k-1\),如果根结点上没有任何儿子是叶子结点,那么先确定一个bud,将的bud依次接到它的叶子结点上,每次叶子结点减少1,一共移动\(k-1\)次,最后答案为\(n-k-1-(k-1)\).如果根结点上有个儿子是叶子结点,那么将\(k\)个bud依次接上去,最后答案为\(n-k-1-k\).具体写法就是dfs,对于一条链,最后一个点一定是叶子结点,叶子结点的父亲是一个bud,bud的父亲是一个叶子结点,就这样分奇偶判断即可.
-
代码:
#include <iostream> #include <iomanip> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #define ll long long #define db double #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; int gcd(int a,int b){return b?gcd(b,a%b):a;} int lcm(int a,int b){return a/gcd(a,b)*b;} int u,v; vector<int> edge[N]; int cnt[N]; void dfs(int u,int fa){ bool leaf=false; for(auto to:edge[u]){ if(to==fa) continue; dfs(to,u); if(cnt[to]==1) leaf=true; //表示这个点的儿子有叶子结点 } if(u!=1){ if(leaf) cnt[u]=2; else cnt[u]=1; } } int main() { #ifdef lr001 freopen("/Users/somnus/Desktop/data/in.txt","r",stdin); #endif #ifdef lr002 freopen("/Users/somnus/Desktop/data/out.txt","w",stdout); #endif int _; scanf("%d",&_); while(_--){ int n; scanf("%d",&n); for(int i=1;i<=n;++i) edge[i].clear(); for(int i=1;i<n;++i){ scanf("%d %d",&u,&v); edge[u].pb(v),edge[v].pb(u); } dfs(1,-1); int flag=0; for(auto to:edge[1]){ if(cnt[to]==1) flag=1; } ll ans=0; for(int i=1;i<=n;++i) ans+=2*(cnt[i]==2); printf("%lld\n",n-ans-flag); } return 0; }
标签:Buds,结点,16,int,Global,叶子,include,bud,define
来源: https://www.cnblogs.com/lr599909928/p/15265765.html
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。