[codeforces#438 E题]Policeman and a Tree
来源:互联网 发布:域名不合法是怎么回事 编辑:程序博客网 时间:2024/06/07 12:45
基于边的树形DP+DP转移一个神奇的二分。
二分要从罪犯的角度去理解,之前一直在纠结一个警察和罪犯的极大极小博弈,没想到可以有这么一个神奇的二分。
写完AC,但感觉理解得不够深刻。
#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>using namespace std;#define INF 0x7f000000#define N 55struct EDGE{ int u,v,w; EDGE(int u=0,int v=0,int w=0):u(u),v(v),w(w){}};vector<EDGE> e;vector<int> g[N];int f[N*2][N][N];int n,m;int ccnt[N];bool isleaf[N];int st;void read(){ scanf("%d",&n); for (int i=1;i<n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); e.push_back(EDGE(u,v,w)); e.push_back(EDGE(v,u,w)); g[u].push_back(e.size()-2); g[v].push_back(e.size()-1); } scanf("%d",&st); scanf("%d",&m); memset(ccnt,0,sizeof(ccnt)); for (int i=1;i<=m;i++){ int x; scanf("%d",&x); ccnt[x]++; } memset(isleaf,0,sizeof(isleaf)); for (int i=1;i<=n;i++) if (g[i].size()==1) isleaf[i]=true;}int dfs(int u,int p){ for (int i=0;i<g[u].size();i++){ EDGE ed=e[g[u][i]]; if (ed.v==p)continue; ccnt[u]+=dfs(ed.v,u); } //printf("ccnt[%d]=%d\n",u,ccnt[u]); return ccnt[u];}int dp(int eid,int s,int s2){ //沿着eid走 int &fval=f[eid][s][s2]; if (fval<INF) return fval; if (s==0) return 0; if (s2==0) exit(-2); EDGE ed=e[eid]; int u=ed.u;int v=ed.v;int w=ed.w; //到达叶子节点//抓住s2个罪犯,往回走 if (isleaf[v]){ fval=w+dp(eid^1,s-s2,s-s2); //printf("fval=%d\n",fval); return fval; } //非叶子节点 //神奇的二分,找到T,表示警察能抓到所有罪犯最小时间 int l=1,r=N*N*N; while(l<r){ int T=(l+r)/2; int sum=0; //不让警察在T时间内抓住的最大罪犯个数 for (int i=0;i<g[v].size();i++){ int v2=e[g[v][i]].v; int w2=e[g[v][i]].w; if (v2==u) continue; //不走回头 //找到尽量大的b,使得当走e[g[u][i]]这条边,可以在<=T的时间内抓住所有罪犯 int b; for(b=1;b<=s2;b++){ if (dp(g[v][i],s,b)<=T) break; } if (b>s2) sum=s2; else sum+=b-1; if (sum>=s2) break; } if (sum>=s2) //存在一种方案使得警察无法在T时间内抓到所有人 l=T+1; else r=T; } fval=w+l; return fval;}int main(){ read(); dfs(st,0); memset(f,127,sizeof(f)); int ans=INF; for (int i=0;i<g[st].size();i++){ EDGE ed=e[g[st][i]]; if (ccnt[ed.v]) ans=min(ans,dp(g[st][i],m,ccnt[ed.v])); } printf("%d\n",ans); //printf("%d",dp(3,1,1)); return 0;}
阅读全文
0 0
- [codeforces#438 E题]Policeman and a Tree
- CodeForces 868 E. Policeman and a Tree
- Codeforces868E Policeman and a Tree -- DP
- Codeforces 438E The Child and Binary Tree
- Codeforces 463E Caisa and Tree(暴力)
- CodeForces 735E Ostap and Tree
- CodeForces 734E - Anton and Tree
- 【27.91%】【codeforces 734E】Anton and Tree
- codeforces 463E . Caisa and Tree
- codeforces 763A-Timofey and a tree 套路题
- Codeforces 763A-Timofey and a tree
- CodeForces 763A Timofey and a tree
- codeforces 764C Timofey and a tree (思维题)
- codeforces 739b Alyona and a tree
- CODEFORCES 739B Alyona and a tree
- 【codeforces 764C】Timofey and a tree
- CodeForces 764C Timofey and a tree
- CodeForces 438E The Child And Binary Tree NTT模板 生成函数应用
- 高并发下线程安全的单例模式(最全最经典)
- 验证器(草稿)
- 使用atom编辑适用于github的.md
- js如何实现不能文本框粘贴
- mCustomScrollbar.js自定义滚动条…
- [codeforces#438 E题]Policeman and a Tree
- Struts2框架详细解析
- bzoj 1225: [HNOI2001] 求正整数
- Wpf Windows SizeToContent
- 避免 php-fpm 耗尽内存导致宕机
- Python(0):Python基础知识
- Python3 日期时间 相关模块(time(时间) / datatime(日期时间) / calendar(日历))
- github
- Git学习简单教程