您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: