topcoder13185 TreePuzzle
https://community.topcoder.com/stat?c=problem_statement&pm=13185
被wck屠了。
考试时候想分类讨论,结果发现情况有点复杂,最后还是没调出来。
回去看了看题解,发现好像是树形DP,状态记得很巧妙。
假设当前红点在$x$,从$fa$来,容易知道此时$fa$是空的。

容易知道以$fa$为根的子树(即如图的绿色圈)中的黑点是可以任意移动的。
因为$fa$是空的,所以我们可以先把红点从$x$移到$fa$,然后将以$x$为子树中的所以黑点任意移动,最后再把红点从$fa$移到$x$。
所以以$x$为根的子树(即如图的蓝色圈)中的黑点也是可以任意移动的。
所以我们只需要知道以$x$为根的子树中的黑点的个数即可。
记$vis[x][fa][c]$表示当前红点在$x$,从$fa$来,且以$x$为根的子树中的黑点的个数为$c$的状态,$1$表示可以到达这种状态,$0$表示不可以到达这种状态。
然后DP即可。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b) for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define p_b(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} inline int sgn(DB x){if(abs(x)<1e-)return ;return(x>)?:-;}
const DB Pi=acos(-1.0); int gint()
{
int res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
}
LL gll()
{
LL res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
} const int maxn=; int n;
int d[maxn+],g[maxn+][maxn+];
int mark[maxn+];
int sz[maxn+][maxn+];//sz[i][j]表示i的父亲为j时,子树i的大小
int bl[maxn+];
int res[maxn+]; void addedge(int u,int v){g[u][++d[u]]=v;} int calsz(int x,int fa)
{
int &res=sz[x][fa],j;
if(res)return res;
res=;
re(j,,d[x])if(g[x][j]!=fa)res+=calsz(g[x][j],x);
return res;
}
int calbl(int x,int fa)
{
int &res=bl[x],j;
res=mark[x];
re(j,,d[x])if(g[x][j]!=fa)res+=calbl(g[x][j],x);
return res;
} queue<int>Q;
int vis[maxn+][maxn+][maxn+];
void push(int x,int fa,int c)
{
if(vis[x][fa][c])return;
vis[x][fa][c]=;
Q.push((x<<)|(fa<<)|c);
} int main()
{
freopen("puzzle.in","r",stdin);
freopen("puzzle.out","w",stdout);
int i,j;
n=gint();
re(i,,n){int fa=gint()+;if(fa)addedge(fa,i),addedge(i,fa);}
re(i,,n)re(j,,d[i])calsz(i,g[i][j]);
re(i,,n)mark[i]=gint();mark[]=;
calbl(,-);
int total=bl[];
re(j,,d[])
{
int v=g[][j];
if(sz[v][]>bl[v])push(v,,bl[v]);
}
res[]=;
while(!Q.empty())
{
int status=Q.front(),x=status>>,fa=(status>>)&,c=status&;Q.pop();//当前红点在x,从fa来,子树内的黑点数为c
res[x]=;
if(total-c<sz[fa][x])push(fa,x,total-c);
int sc=;
re(j,,d[x])if(g[x][j]!=fa)sc+=sz[g[x][j]][x];
re(j,,d[x])if(g[x][j]!=fa)
{
int v=g[x][j];
for(int c2=;c2<=c && c2<sz[v][x];c2++)if(c-c2<=sc-sz[v][x])push(v,x,c2);
}
}
re(i,,n)PF("%d ",res[i]);PF("\n");
return ;
}
topcoder13185 TreePuzzle的更多相关文章
- TreePuzzle 一点感想
题目链接 这一道题看起来像是一道贪心的水题,但是情况较难考虑周全,比如下图,我就考虑漏了这种情况,点0是可以移动到点1的.然后我就各种奇怪的分类讨论.最终还是没能A,决定放弃治疗. 然后我看了看解答, ...
随机推荐
- 利用System V消息队列实现回射客户/服务器
一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并 ...
- Java基础知识强化之集合框架笔记10:Collection集合使用的步骤
集合使用的步骤: (1)创建集合对象 (2)创建元素对象 (3)把元素添加到集合 (4)遍历集合: • 通过集合对象获取迭代器对象 • 通过迭代器对象的hasnext()方法判断是否有元素 ...
- WEB前端开发规范文档(转)
http://codeguide.bootcss.com/ 编写灵活.稳定.高质量的 HTML 和 CSS 代码的规范上面的文档 再结合下面的规范: 无论是从技术角度还是开发视角,对于web前端开发 ...
- ie下面兼容性问题的一些总结
最后一次搞ie兼容性问题,以后都可以不管了0.0 1.浮动兼容性 1.1IE6下的双边距BUG 在IE6下,块元素有浮动和横向margin的时候,最边上元素的横向margin值会被放大成两倍 解决办法 ...
- EXPDP IMPDP 知识总结
Data Pump Export ATTACH Default: job currently in the user's schema, if there is only one Purpose(目的 ...
- Swift - 30 - 可变参数
//: Playground - noun: a place where people can play import UIKit // 可变参数一定要放在所有定义参数的最后面, 和其他参数的定义方式 ...
- cas sso单点登录系列5_cas单点登录增加验证码功能完整步骤
转:http://blog.csdn.net/ae6623/article/details/8919718 本篇教程cas-server端下载地址:解压后,直接放到tomcat的webapp目录下就能 ...
- ReetrantLock Synchronized Atomic的性能对比
之前看到了一篇帖子关于Lock和Synchronized的性能,写的是Lock比Synchronized的性能要好,可是,我试了下,结果却不是这样的,我所使用的JDK的版本是1.7,可能跟原帖作者用的 ...
- 《C++游戏开发》笔记十四 平滑过渡的战争迷雾(二) 实现:真正的迷雾来了
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9712321 作者:七十一雾央 新浪微博:http:/ ...
- 富文本web编辑器(UEditor)
展示效果: