JZOJ 1301. treecut
2017-07-09 21:51
169 查看
1301. treecut (Standard IO)
Time Limits: 1000 ms Memory Limits: 131072 KBDescription
有一个N个节点的无根树,各节点编号为1..N,现在要求你删除其中的一个点,使分割开的连通块中节点个数都不超过原来的一半多。Input
第一行:一个整数N (1 <= N <= 10,000)。 后面有N-1行:每行两个整数 X 和 Y,表示一个边连接的两个节点号。Output
输出所有可能选择的点。如果有多个节点,按编号从小到大输出,每个一行。 如果找不到这样的点,输出一行:”NONE”.Sample Input
101 2
2 3
3 4
4 5
6 7
7 8
8 9
9 10
3 8
Sample Output
38
Data Constraint
Hint
样例说明: 删除3号或8号节点,则分枝最多有5个节点题解
人为规定1为根然后dfs搜索就可以了
每次求出节点i的所有儿子的儿子数
然后判断是否满足小于等于n/2
代码
#include<cstdio> #include<algorithm> #include<vector> #define N 10001 using namespace std; vector<long>map ; long n; long lc ,rb ,ans ; bool b ; void build(long now) { long i,next; b[now]=true; for(i=0;i<map[now].size();i++)if(!b[map[now][i]]){ if(!lc[now])lc[now]=map[now][i]; else rb[next]=map[now][i]; next=map[now][i]; build(next); } } long dfs(long now) { long i,q,num=0; bool t=true; for(i=lc[now];i;i=rb[i]){ if((q=dfs(i))-1>=long(double(n)/2+0.9)) t=false; num+=q; } if(t&&n-(num+1)<=long(double(n)/2+0. b255 9))ans[++ans[0]]=now; return num+1; } int main() { long i,x,y; scanf("%ld",&n); for(i=1;i<n;i++){ scanf("%ld%ld",&x,&y); map[x].push_back(y); map[y].push_back(x); } build(1); dfs(1); if(!ans[0])printf("NONE\n"); else{ sort(ans+1,ans+ans[0]+1); for(i=1;i<=ans[0];i++) printf("%ld\n",ans[i]); } return 0; }
相关文章推荐
- 【2018.3.17】模拟赛之二-ssl1862&jzoj1366 删数【区间dp】
- JZOJ 5602 Cti
- JZOJ5610. 【NOI2018模拟3.29】simple
- [JZOJ 1283]排序统计
- 【JZOJ】3187 的士
- JZOJ 1161.机器人M号
- JZOJ 3104.疫情控制
- JZOJ.4300[NOIP2015模拟11.3]装饰大楼 解题报告
- {题解}[jzoj3405]【NOIP2013模拟】舞台表演
- jzoj3395 Freda的传呼机
- 【JZOJ 3427】归途与征程
- 【JZOJ 3432】【OnlineJudge 1061】小M的服务器(含斜率优化解释)
- 【JZOJ 4388】 染色
- 【JZOJ 3466】选课
- 【JZOJ 4587】Snow的追寻
- 【JZOJ 4598】 准备食物
- {题解}[jzoj1237]餐桌
- [JZOJ4624] 字符串匹配
- jzoj 1388 【2012.02.25普及组】探索的奶牛 结题报告