Sicily 1140 国王的遗产
2013-11-22 11:32
295 查看
贪心,主要卡在划分树的子树上。
#include <iostream> using namespace std; #include <stdio.h> #include <vector> #include <algorithm> #include <deque> #include <memory.h> vector<int> tree[30002]; int node_ctr[30002]; int n,k; vector<int> result; int set_node_ctr(int root) { if (node_ctr[root]!=0) return node_ctr[root]; int s=tree[root].size(); int i,tmp; for (i=0;i<tree[root].size();i++) { if (tree[root][i]==0) s--; } if (s==0) { node_ctr[root] = 1; return node_ctr[root]; } tmp = 1; for (i=0;i<tree[root].size();i++) { if (tree[root][i]!=0) tmp+=set_node_ctr(tree[root][i]); } node_ctr[root] = tmp; return tmp; } int get_minID(int root) { deque<int> q; int minid = root; q.push_back(root); int tmp; while (!q.empty()) { tmp=q.front(); q.pop_front(); if (tmp<minid) minid=tmp; for(int i=0;i<tree[tmp].size();i++) { if (tree[tmp][i]!=0) q.push_back(tree[tmp][i]); } } return minid; } void delete_node(int root) { int flag=0; for (int i=1;i<=n;i++) { for (int j=0;j<tree[i].size();j++) { if (tree[i][j]==root) { tree[i][j]=0; flag=1; break; } } if (flag==1) break; } } int get_next_root(int total, int root_id) { int t1,t2,r1,r2; int tmp = total/2; int i; int num; deque<int> q; t1=t2=-1; r1=r2=-1; q.push_back(root_id); while (!q.empty()) { int top_id = q.front(); q.pop_front(); for (i=0;i<tree[top_id].size();i++) { num = tree[top_id][i]; if (num==0) continue; q.push_back(num); if (node_ctr[num]!=0&&node_ctr[num]<=tmp) { if (node_ctr[num]>t1) { t1=node_ctr[num]; r1=num; } } else if (node_ctr[num]==t1) { if (get_minID(num)<r1) r1=num; } if (node_ctr[num]!=0&&total-node_ctr[num]<=tmp) { if (total-node_ctr[num]>t2) { t2 = total-node_ctr[num]; r2 = num; } else if (total-node_ctr[num]==t2) { if (get_minID(num)>r2) r2=num; } } } } if (t1<t2) return r2; else if (t1==t2 && get_minID(r1) == get_minID(root_id)) { delete_node(r2); } else { delete_node(r1); } return -1; } void make_tree(int root) { int i,j; for (i=0;i<tree[root].size();i++) { int tmp = tree[root][i]; for (j=0;j<tree[tmp].size();j++) { if (tree[tmp][j]==root) tree[tmp][j]=0; } make_tree(tmp); } } void solve() { memset(node_ctr, 0, sizeof(node_ctr)); set_node_ctr(1); int i, root; root = 1; int total = n; for (i=0;i<k-1;i++) { int tmp = get_next_root(total, root); if (tmp > 0) root = tmp; memset(node_ctr, 0, sizeof(node_ctr)); set_node_ctr(root); result.push_back(total - node_ctr[root]); total = node_ctr[root]; } int sum = 0; for (i=0;i<result.size();i++) sum+=result[i]; result.push_back(n-sum); } int main() { int i; int x,y; while(scanf("%d",&n)!=EOF) { scanf("%d",&k); result.clear(); for (i=0;i<=n;i++) { tree[i].clear(); } for (i=0;i<n-1;i++) { scanf("%d%d",&x, &y); tree[x].push_back(y); tree[y].push_back(x); } make_tree(1); solve(); for (i=0;i<result.size()-1;i++) cout << result[i] << " "; cout << result[i] << endl; } return 0; }
相关文章推荐
- SWT设置Lable标签透明
- Centos下安装xinetd以及minicom、tftp的配置
- Android消息提示框和对话框
- KVM虚拟机IO处理过程(一) ----Guest VM I/O 处理过程
- i = i++ 在java字节码层面的分析
- vs2010 调试程序加载符号慢
- JavaWeb_01_response_生成随机验证码
- 巴菲特的金玉良言
- c# 以类名为参创建父类相同的类的实例
- 如何处理Oracle中TEMP表空间满的问题
- Discuz 默认模板文件目录结构大全
- 常用JavaScript库CDN服务 http://jscdn.upai.com/
- jcxz+call+ret 指令实验
- flex外包公司—技术分享:flex 优化技巧 收集[提升性能]
- android动态壁纸周期
- 如何在所有情况中挑选
- [LeetCode]Longest Palindromic Substring
- notepad++ 去除 重复行
- Android 通信领域
- Sicily 1048 Inverso