JZOJ 5442. 【NOIP2017提高A组冲刺11.1】荒诞
来源:互联网 发布:手机淘宝怎么没有直播 编辑:程序博客网 时间:2024/06/05 04:08
题目
有一个n个点,m条边的无向图,第i个点建立一个旅游站点的费用是c_i。特别地,这张图中的任意两点间不存在节点数超过10的简单路径。
我想要建造一些旅游站点使得每个点要么建立了旅游站点,要么与它有边直接相连的点里至少有一个点建立了旅游站点。我还希望这个建造方案总花费尽量少。
请求出这个花费。
数据范围
对于前30%的测试点,满足1<=n<=20,0<=m<=50。
对于另外15%的测试点,满足每个连通块都是一棵树。
对于100%的测试点,满足
题解
30分肯定枚举选哪个不选哪个。
另15分直接树形DP。
AC做法
题目条件
选了一个点,与之相连的点可以不选。
以任何一点为根的dfs树深度不超过10。
困惑点
有返祖边干扰了转移。
只确定当前点的状态满足不了题目的需求。
准确做法
考虑树形DP。
考虑怎么样避免返祖边的干扰。一个新知识:欧拉序。
欧拉序,就是从根遍历到每个点,再回到根的经过的点的序列。
如果第二次到点x,说明x的子树已经处理完了,可以更新到x。
那么可以考虑基于欧拉序的DP。
设
那么枚举状态s,讨论x是否被选两种情况就可以DP。(设x的父亲是y)
①没有被选:由于返祖边的干扰,我们先确定与之有边连着的祖先是否被选,如果是的话x一定会被覆盖到
②被选:那么会影响到与之有边连着的祖先。
设这个新状态为s1,则有
接下来递归子树。由于第一次遍历到x点时为讨论到x的子树更新x的情况,所以
代码
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define N 20010#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;struct note{ int to,next;};note edge[N*5/2];int i,j,k,l,n,m;int dep[N],ans,fa[N];int c[N],u,v;int head[N],tot;int f[2][59050];int _3[13];bool bz[N],bb[13];int read(){ int fh=1,res=0;char ch; while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')fh=-1,ch=getchar(); while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar(); return res*fh;}void lb(int x,int y){ edge[++tot].to=y; edge[tot].next=head[x]; head[x]=tot;}void mix(int &x,int y){x=x<y?x:y;}void dg(int x){ bz[x]=1; int o=dep[x]&1; bool pp; memset(f[o],63,sizeof(f[o])); memset(bb,0,sizeof(bb)); int i,s,s1; for(i=head[x];i;i=edge[i].next) if(dep[edge[i].to]<dep[x])bb[dep[edge[i].to]]=1; fo(s,0,_3[dep[x]]-1) if(f[1^o][s]<1061109567){ s1=s+_3[dep[x]]*2; pp=0; fo(i,1,dep[x]-1) if(bb[i]){ if(((s1/_3[i])%3)==0)s1+=_3[i]; if(((s/_3[i])%3)==2)pp=1; } mix(f[o][s1],f[1^o][s]+c[x]); if(pp)mix(f[o][s+_3[dep[x]]],f[1^o][s]); else mix(f[o][s],f[1^o][s]); } for(i=head[x];i;i=edge[i].next) if(!bz[edge[i].to]){ fa[edge[i].to]=x; dep[edge[i].to]=dep[x]+1; dg(edge[i].to); fo(s,0,_3[dep[edge[i].to]]-1) f[o][s]=min(f[1^o][s+_3[dep[edge[i].to]]],f[1^o][s+_3[dep[edge[i].to]]*2]); }}int main(){ _3[1]=1;fo(i,2,12)_3[i]=_3[i-1]*3; n=read(),m=read(); fo(i,1,n)c[i]=read(); fo(i,1,m){ u=read(),v=read(); lb(u,v),lb(v,u); } fo(i,1,n) if(!bz[i]){ memset(f,63,sizeof(f)); f[0][0]=0; dep[i]=1; dg(i); ans+=min(f[1][1],f[1][2]); } printf("%d",ans); return 0;}
- JZOJ 5442. 【NOIP2017提高A组冲刺11.1】荒诞
- 【JZOJ 5442】【NOIP2017提高A组冲刺11.1】荒诞
- 【NOIP2017提高A组冲刺11.1】荒诞
- 【JZOJ5442】【NOIP2017提高A组冲刺11.1】荒诞[状压dp]
- JZOJ5442【NOIP2017提高A组冲刺11.1】荒诞 三进制状压+欧拉序
- JZOJ5442. 【NOIP2017提高A组冲刺11.1】荒诞
- JZOJ 5440. 【NOIP2017提高A组冲刺11.1】背包
- JZOJ 5441. 【NOIP2017提高A组冲刺11.1】序列
- 【JZOJ 5441】【NOIP2017提高A组冲刺11.1】序列
- JZOJ 5440. 【NOIP2017提高A组冲刺11.1】背包
- JZOJ 5441. 【NOIP2017提高A组冲刺11.1】序列
- [JZOJ5442]【NOIP2017提高A组冲刺11.1】荒诞([BZOJ3060]【POI2012】Tour de Byteotia)
- 【JZOJ 5445】【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5443. 【NOIP2017提高A组冲刺11.2】字典序
- jzoj【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5444. 【NOIP2017提高A组冲刺11.2】救赎
- JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格
- JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格
- 微服务(Microservices)- 文章翻译
- 自学数据库E-R图
- python核心编程课后习题-正则式2
- android6.0 读取storage文件夹需要手动检测读取权限
- C#存储过程调用的三个方法
- JZOJ 5442. 【NOIP2017提高A组冲刺11.1】荒诞
- springboot jpa Query使用原生SQL例子--测试通过
- 复制一个web项目,项目名称如何修改,才能保证项目正常运行
- html5基础学习日记2_列表
- POJ 3764 The xor-longest Path 01字典树+dfs
- Struts2文件上传
- MatLab视频学习笔记(21世纪电子论坛原创视频)-01
- java 基础 运算符
- 大数相乘FFT