Tree NOIp2013-Training Series #4
来源:互联网 发布:通用网址和中文域名 编辑:程序博客网 时间:2024/06/08 09:28
Description
给出N 个点的树和K,问能否把树划分成N/K 个连通块,且每个连通块的点数都是K。
Input
第1 行,1 个整数T,表示数据组数。接下来T 组数据,对于每组数据:
第1 行,2 个整数N;K。
接下来(N -1) 行,每行2 个整数Ai,Bi,表示边(Ai,Bi)。点用1,2,...,N 编号。
Output
对于每组数据,输出YES或NO。
Sample Input
24 21 22 33 44 21 21 31 4
Sample Output
YESNO
Hint
对于60% 的数据,1<=N,K<=10^3;
对于100% 的数据,1<=T<=10,1<=N,K<=10^5。
【分析】
首先想清楚,如果答案是YES,那么这棵树的拆分方法是唯一的!
这个结论要严格的证明我也不会证,但是仔细想想好像还是可以理解。
于是我们任选一个点为根,开始dfs,dfs的核心目的是找出子树的节点数count[i]
当然,单纯的找count是不行的,我们要增加如下操作
1.dfs之前,ans=true;
2.在以i为根的子树dfs的时候,如果i的某个儿子节点j的count[j]==K,那么j子树是要独立成为以个K点集合,在计算count[i]的时候就不要把count[j]加进去,相当于删除j这个子树;
3.如果i的某个儿子节点j的count[j]<K,说明这棵子树节点数不够,必须把节点i以及更多节点加入这个集合,所以必须count[i]+=count[j],相当于合并;
4.如果count[j]>K,那么这已经超出我们的要求了,所以直接{ans=false;return;}
一开始可能觉得这个算法有点贪心的意味在里面,可能是错的,但是经过草稿纸分析,代码亲测,这个算法是对的!
只需要注意各种memset
然后就可以去AC了!
【代码】
#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int MAXN=100005;int N,K;int y[MAXN<<1],next[MAXN<<1],last[MAXN],cnt[MAXN],tot;bool f[MAXN],ans;void _in(int &x){char t=getchar();while(t<'0'||'9'<t) t=getchar();for(x=0;'0'<=t&&t<='9';x=x*10+t-'0',t=getchar());}void _init(){memset(f,0,sizeof(f));memset(y,0,sizeof(y));memset(next,0,sizeof(next));memset(last,0,sizeof(last));memset(cnt,0,sizeof(cnt));_in(N);_in(K);tot=0;int a,b;for(int i=1;i<N;i++){_in(a);_in(b);tot++;y[tot]=b;next[tot]=last[a];last[a]=tot;tot++;y[tot]=a;next[tot]=last[b];last[b]=tot;}ans=true;}void _DFS(int x){f[x]=true;cnt[x]=1;for(int j=last[x];j;j=next[j]) if(!f[y[j]]){_DFS(y[j]);if(ans==false) return;if(cnt[y[j]]<K){cnt[x]+=cnt[y[j]];if(cnt[x]>K){ans=false;return;}}else if(cnt[y[j]]>K){ans=false;return;}}}void _solve(){ _DFS(1);printf(ans?"YES\n":"NO\n");}int main(){int T;scanf("%d",&T);while(T--){ _init(); _solve();}return 0;}
- Tree NOIp2013-Training Series #4
- Graph NOIp2013-Training Series #4
- Sequence NOIp2013-Training Series #4
- Difference NOIp2013-Training Series #1
- Increasing NOIp2013-Training Series #1
- Sum of xor NOIp2013-Training Series #2
- Sum of product NOIp2013-Training Series #2
- Apple Training Series : iLife 06 (Apple Training Series)
- Apple Training Series : GarageBand 3 (Apple Training Series)
- 【NOIP2013模拟联考5】军训(training)
- 【NOIP2013模拟联考5】军训(training) 题解
- NOIP2013模拟联考5】军训(training)
- Apple Training Series: Desktop and Portable Systems
- 【NOIP2013模拟联考5】军训(training) 题解+代码
- NOIP2013
- noip2013
- noip2013
- Apple Training Series: Mac OS X Support Essentials
- linux下上传下载命令SFTP ,FTP
- 树莓派(Raspberry Pi):完美的家用服务器
- 完美匹配中文的Php正则表达式
- Notpad++ json插件的使用
- 飞机模型
- Tree NOIp2013-Training Series #4
- linux系统记录
- iOS的主要框架介绍
- OCP-1Z0-053-V12.02-372题
- Oracle VM VirtualBox各种显示模式切换 热键
- 浅谈Android五大布局(二)——RelativeLayout和TableLayout
- 【代码】邮件群发机PHP实现实例分享
- 多表关联update
- UTF8二进制及明文字符窜转化