[二分 树形DP] CEOI2017. Mousetrap
来源:互联网 发布:访问服务器8080端口 编辑:程序博客网 时间:2024/06/13 00:51
第一次做这种DP题
以
如果老鼠往子树中走,我们肯定是等它走到某个位置不能走了,然后把他当前在的位置当根节点这段路上的其他支路都封死,这样是最优的。
那么我们可以树形DP出老鼠走到以这个点为根的子树的时候,需要的最少步数。
令
那么
那么可以二分答案,然后从
这样复杂度就是
#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int N=1000010;int n,m,t,cnt,G[N],w[N],d[N];struct edge{ int t,nx;}E[N<<1];inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void rea(int &x){ char c=nc(); x=0; for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());}inline void addedge(int x,int y){ E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt; d[x]++; E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt; d[y]++;}int fa[N],dpt[N];int Q[N],qt;void dfs(int x,int f){ fa[x]=f; dpt[x]=dpt[f]+1; for(int i=G[x];i;i=E[i].nx) if(E[i].t!=f) dfs(E[i].t,x);}void calc(int x,int y){ for(int i=G[x];i;i=E[i].nx) if(E[i].t!=fa[x]) calc(E[i].t,y+d[x]-1); if(d[x]==1) w[x]=y; else if(d[x]==2) w[x]=y+1; else{ int imax=0,sec=0; for(int i=G[x];i;i=E[i].nx) if(E[i].t!=fa[x]) if(w[E[i].t]>imax) sec=imax,imax=w[E[i].t]; else sec=max(sec,w[E[i].t]); w[x]=sec; }}int vis[N];inline bool check(int X){ int lst=0; for(int k=1;k<=qt;k++){ int x=Q[k],cur=0; for(int i=G[x];i;i=E[i].nx) if(E[i].t!=fa[x] && w[E[i].t]+lst>X && !vis[E[i].t]) cur++; lst+=cur; if(lst>k || lst>X) return 0; } return 1;}int main(){ rea(n); rea(t); rea(m); for(int i=1,x,y;i<n;i++) rea(x),rea(y),addedge(x,y); dfs(t,0); for(int u=m;u!=t;u=fa[u]) Q[++qt]=u,vis[u]=1; for(int k=qt,cur=0;k;k--){ int x=Q[k]; cur+=d[x]-2; for(int i=G[x];i;i=E[i].nx) if(E[i].t!=fa[x] && !vis[E[i].t]) calc(E[i].t,cur+(x==m)); } int L=0,R=n,mid,ans; while(L<=R) check(mid=L+R>>1)?R=(ans=mid)-1:L=mid+1; printf("%d\n",ans); return 0;}
阅读全文
0 0
- [二分 树形DP] CEOI2017. Mousetrap
- CEOI2017 D1T3 mousetrap 树形dp+二分答案
- hdu3586,树形dp+二分
- hdu3586(树形dp+二分)
- hdu3586(二分+树形dp)
- hdu 3586 树形dp +二分
- hdu3586(树形DP+二分答案)
- hdu 3586 二分+树形dp
- hdu3586 树形dp+二分求解
- hdu1054 【树形dp】【二分匹配】
- hdu 3586(树形dp+二分)
- Hdu 6241 二分+树形dp
- hdu3586(树形DP+二分,割边)
- hdu 3586 Information Disturbing 树形dp+二分
- 树形DP+二分(Information Disturbing HDU3586)
- HDU 3586 Information Disturbing 二分+树形DP
- HDU 3586 Information Disturbing (树形DP+二分)
- HDU 3586 Information Disturbing 树形DP+二分
- HDFS架构和读写流程详解
- Tomcat和Java及servlet使用注意事项
- KD树的C++实现
- sqlalchemy数据操作
- GUI编程——Tkinter、pyinstaller
- [二分 树形DP] CEOI2017. Mousetrap
- 深入理解不同的二分查找C++
- 《Effective C++》读后总结(三)尽量使用const
- Mac 中 Homebrew 的一些使用笔记
- 【整体二分+树状数组区间加区间和】BZOJ3110 [Zjoi2013]K大数查询
- 用龙芯1c库在裸机编程环境中实现硬件定时器中断
- 第十课、C运算符
- [转载自宋博士博客]如何在ANSYS WORKBENCH中进行多载荷步的静力分析?
- 如何在Windows上编译64位QT