[2017纪中11-3]机房比教室好多了 博弈+树型DP
来源:互联网 发布:java算法书籍推荐 编辑:程序博客网 时间:2024/06/05 20:21
题面
先考虑出发点在x,先手玩以x为根这棵子树的答案。
首先不难证明,a[x]变大,不会变得更劣。
那我们考虑先手拿完一个石头后走向一个a[son]>=a[x]的儿子,这样肯定是不明智的,因为假如对手把你推回x,你当然不能和他一直这样推来推去(你肯定先死),所以你会选择去别的儿子,但这当然不如一开始就去别的儿子(因为a[x]更大)。
再考虑先手拿完一个石头后走向一个a[son]
#include<iostream>#include<cstdio>#include<cstring>#define ll long longusing namespace std;const int maxn=1000010;int n,a[maxn],s[maxn];bool f[maxn];struct edge{ int t; edge *next;}*con[maxn];int read(){ int x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();} return x;}void ins(int x,int y){ edge *p=new edge; p->t=y; p->next=con[x]; con[x]=p;}void dfs(int v,int fa){ for(edge *p=con[v];p;p=p->next) if(p->t!=fa) { dfs(p->t,v); if(a[p->t]<a[v]&&s[p->t]==0) s[v]++; }}void dfs2(int v,int fa){ if(a[fa]<a[v]) s[v]+=(f[v]==0); for(edge *p=con[v];p;p=p->next) if(p->t!=fa) { f[p->t]=(s[v]-(a[v]>a[p->t]&&s[p->t]>0)); dfs2(p->t,v); }}int main(){ n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); ins(x,y); ins(y,x); } dfs(1,0); for(int i=1;i<=n;i++) if(s[i]>0) printf("%d ",i); return 0;}
考场怕爆栈dfs序版:
#include<iostream>#include<cstdio>#include<cstring>#define ll long longusing namespace std;const int maxn=1000010;int n,a[maxn],s[maxn],fa[maxn],st[maxn],dfn[maxn],tim;bool f[maxn];struct edge{ int t; edge *next;}*con[maxn];int read(){ int x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();} return x;}void ins(int x,int y){ edge *p=new edge; p->t=y; p->next=con[x]; con[x]=p;}void dfs(){ int top=1;st[1]=1;fa[1]=0; while(top>0) { int v=st[top--]; dfn[++tim]=v; for(edge *p=con[v];p;p=p->next) if(p->t!=fa[v]) { fa[p->t]=v; st[++top]=p->t; } } for(int i=n;i>1;i--){int v=dfn[i];if(a[v]<a[fa[v]]&&s[v]==0) s[fa[v]]++;} for(int i=2;i<=n;i++) { int v=dfn[i]; f[v]=(s[fa[v]]-(a[fa[v]]>a[v]&&s[v]>0)); if(a[fa[v]]<a[v]) s[v]+=(f[v]==0); }}int main(){ n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); ins(x,y); ins(y,x); } dfs(); for(int i=1;i<=n;i++) if(s[i]>0) printf("%d ",i); return 0;}
其实并不需要这么麻烦。考虑一条边(x,y),x,y之间只会转移一次(因为a[x]
#include<cstdio>#include<algorithm>using namespace std;const int N=1e6+10;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f;}struct node{ int to,nxt;}tree[N<<2];int num[N],head[N],cnt=0,vis[N],n,can[N];void add(int x,int y){ tree[++cnt]=node{y,head[x]}; head[x]=cnt;}int dfs(int u,int fa){ if (vis[u]) return can[u]; vis[u]=1;can[u]=0; for (int i=head[u];i;i=tree[i].nxt){ int v=tree[i].to; if (v==fa) continue; if (num[u]>num[v]&&!dfs(v,fa)){ can[u]=1; break; } } return can[u];}int main(){ n=read(); for (register int i=1;i<=n;++i) num[i]=read(); for (register int i=1,x,y;i<n;++i) x=read(),y=read(), add(x,y),add(y,x); for (register int i=1;i<=n;i++) if (dfs(i,0)) printf("%d ",i);}
阅读全文
0 0
- [2017纪中11-3]机房比教室好多了 博弈+树型DP
- JZOJ 5448. 【NOIP2017提高A组冲刺11.3】机房比教室好多了
- 【NOIP2017提高A组冲刺11.3】机房比教室好多了
- JZOJ5448. 【NOIP2017提高A组冲刺11.3】机房比教室好多了
- 比我老婆好多了
- 做的比上次登陆好多了
- 据说 Nginx 性能比 Apache 好多了
- vc++.net好多函数比vc++6增强了
- ecshop配色插件安装 比 黑色主题 好多了
- ecshop配色插件安装 比 黑色主题 好多了
- 使用Flot绘制曲线图(效果比JfreeChat好多了)
- 开机优化win批处理,有源码,比360好多了
- win清理垃圾批处理 有源码,比360好多了
- 高端多媒体机房教室租赁
- 我勒个去,你们疯了吧?webOS比Android好多了!
- 买了两本系统分析师的书比网上的资料好多了
- 杀毒处理程序win批处理 有源码,比360好多了 可靠多了
- 概率DP 换教室
- Android开发页面去掉顶部标题栏
- 2017.11.3 LeetCode
- C语言入门——数字特征值
- hibernate查询list结果集结果都是一样
- s3c2440 ARM9 裸机驱动第一篇-GPIO驱动(C)
- [2017纪中11-3]机房比教室好多了 博弈+树型DP
- JAVA内存模型
- cipher
- Ubuntu安装Tomcat
- hiERROR: Value '0000-00-00' can not be represented as java.sql.Timestamp
- SQL分组查询
- java 集合遍历Iterator/foreach
- 下载并升级更新pip
- Spark 计算框架