bzoj 2799 [Poi2012]Salaries 贪心
2016-11-16 10:05
330 查看
感觉自己语文水平捉鸡,粘一下吴大爷的题解吧。。。
“
我们维护以每一个节点为根的子树内部有多少个没有确定权值的点,另外,我们利用一个数组维护每个权值已经给了哪个节点.
我们从小到大遍历每个权值,若这个权值当前并没有确定给哪个节点,则将其压入栈中;否则我们在对应节点的子树中进行一系列确定操作:
我们维护栈中有多少个权值,以及有多少个自由权值.(这个是什么一会再说)
若未确定的节点数正好等于当前的自由权值数与栈中的权值总数,显而易见这些权值都应该分配给这棵子树.但是只有只有一个儿子的情况才能确定这个权值.所以我们不断在链上去找即可.这个过程可能确定了一些权值,随后我们将栈清空,并令自由权值的数目为0.因为他们只能被拘束在这颗子树内,而不能去别的地方.
若不然,我们将自由权值及栈中的权值分配给这棵子树所需要的数目,剩下的全部变成自由权值.
我们发现栈中的权值和自由权值很像,但是为什么不都搞成自由权值,而是非要维护一个栈呢?
这个问题显而易见:自由权值都是可以互相交换的(等价的),而栈中的元素显然不是!
”
“
我们维护以每一个节点为根的子树内部有多少个没有确定权值的点,另外,我们利用一个数组维护每个权值已经给了哪个节点.
我们从小到大遍历每个权值,若这个权值当前并没有确定给哪个节点,则将其压入栈中;否则我们在对应节点的子树中进行一系列确定操作:
我们维护栈中有多少个权值,以及有多少个自由权值.(这个是什么一会再说)
若未确定的节点数正好等于当前的自由权值数与栈中的权值总数,显而易见这些权值都应该分配给这棵子树.但是只有只有一个儿子的情况才能确定这个权值.所以我们不断在链上去找即可.这个过程可能确定了一些权值,随后我们将栈清空,并令自由权值的数目为0.因为他们只能被拘束在这颗子树内,而不能去别的地方.
若不然,我们将自由权值及栈中的权值分配给这棵子树所需要的数目,剩下的全部变成自由权值.
我们发现栈中的权值和自由权值很像,但是为什么不都搞成自由权值,而是非要维护一个栈呢?
这个问题显而易见:自由权值都是可以互相交换的(等价的),而栈中的元素显然不是!
”
#include <bits/stdc++.h> using namespace std; #define N 1000010 int n,root,top; vector<int>vec ,pos ; int val ,fa ,use ,size ,st ; queue<int>que; void get(int x) { while(top) { val[x]=st[top--]; if(vec[x].size()!=1)return; x=vec[x][0]; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&fa[i],&val[i]); if(fa[i]==i)root=i,val[i]=n; else vec[fa[i]].push_back(i); use[val[i]]=1; } que.push(root); while(!que.empty()) { int t=que.front();que.pop(); st[++top]=t;size[t]=1; for(int i=0;i<vec[t].size();i++) que.push(vec[t][i]); } for(int i=top;i>=1;i--) { for(int j=0,t;j<vec[st[i]].size();j++) { size[st[i]]+=size[t=vec[st[i]][j]]; if(!val[t]) pos[val[st[i]]].push_back(t); } } int cnt=0,p,rem=0,sum=0; top=0; for(int i=1;i<=n;i++) { if(!use[i])st[++top]=i; else { int t=pos[i].size(); cnt+=t;if(t)p=pos[i][0]; for(int j=0;j<t;j++) sum+=size[pos[i][j]]; if(!use[i+1]) { if(!cnt)continue; rem=top+rem-sum; if(cnt==1&&!rem)get(p); sum=0;cnt=0;top=0; } } } for(int i=1;i<=n;i++) printf("%d\n",val[i]); return 0; }
相关文章推荐
- BZOJ2799: [Poi2012]Salaries
- [BZOJ2799][Poi2012]Salaries
- bzoj 2799 [Poi2012]Salaries 性质+二分
- 【BZOJ2799】[Poi2012]Salaries 乱搞
- [BZOJ 2799]POI 2012 Salaries
- 【BZOJ】【P2802】【POI2012】【Warehouse Store】【题解】【贪心】
- 【bzoj2802】[Poi2012]Warehouse Store 贪心+堆
- 【BZOJ 2802】 2802: [Poi2012]Warehouse Store (贪心)
- bzoj 2802 [Poi2012] Warehouse Store 贪心+堆
- bzoj 2789 [Poi2012]Letters 贪心+逆序对
- bzoj2796 [Poi2012]Fibonacci Representation 贪心
- 【BZOJ】2802: [Poi2012]Warehouse Store(贪心)
- BZOJ 2802 Poi2012 Warehouse Store 堆+贪心
- [bzoj2802][Poi2012]Warehouse Store_贪心_堆
- bzoj 2792: [Poi2012]Well【二分+贪心】
- bzoj 2796[Poi2012]Fibonacci Representation 贪心
- bzoj 3060[Poi2012]Tour de Byteotia 贪心+生成树
- bzoj 2802: [Poi2012]Warehouse Store 贪心+优先队列
- BZOJ_2802_[Poi2012]Warehouse Store_堆+贪心
- 【bzoj2802】[Poi2012]Warehouse Store 贪心+堆