【BZOJ4042】【CERC2014】parades 状压DP
题目大意
给你一棵\(n\)个点的树和\(m\)条路径要求你找出最多的路径,使得这些路径不共边。特别的,每个点的度数\(\leq 10\)。
\(n\leq 1000,m\leq \frac{n(n-1)}{2}\)
题解
先对于每个点把相邻的边编号。
考虑状压DP。
设\(f_{i,j}\)为以\(i\)个点的子树内,状态为\(j\)的边的子树内的边也没有选(这些边也没选),所选的最多路径数。
然后对于每个点有很多种选法,分为两类:1.某条边不选,选对应的子树;2.选\(1\)~\(2\)条边和对应的路径,那么这些路径经过的边都不能选。
然后直接状压DP。
对于每个点来说,总共有最多\(O(d^2)\)种转移。考虑每个儿子的贡献,就是\(O(d)\)。
时间复杂度:\(O(n^2+nd2^d)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
struct list
{
int t[1000010];
pii v[1000010];
int h[1010];
int n;
void clear()
{
memset(h,0,sizeof h);
n=0;
}
void add(int x,pii y)
{
n++;
v[n]=y;
t[n]=h[x];
h[x]=n;
}
};
list l;
int f[1010][1<<10];
int g[1010];
int c[1010][20];
int d[1010];
int ns[12][12];
int e[1010];
void dfs2(int x,int fa,int t,int s)
{
int fc;
int i;
for(i=1;i<=d[x];i++)
if(c[x][i]==fa)
fc=i;
g[x]=s+f[x][((1<<d[x])-1)^(1<<(fc-1))];
e[x]=t;
for(i=1;i<=d[x];i++)
if(c[x][i]!=fa)
dfs2(c[x][i],x,t,s+f[x][((1<<d[x])-1)^(1<<(fc-1))^(1<<(i-1))]);
}
int dd[1010];
int ff[1010];
int lca[1010][1010];
void dfs(int x,int fa,int dep)
{
ff[x]=fa;
dd[x]=dep;
int i;
for(i=1;i<=d[x];i++)
if(c[x][i]!=fa)
dfs(c[x][i],x,dep+1);
}
int getlca(int x,int y)
{
if(x==y)
return x;
if(lca[x][y])
return lca[x][y];
if(dd[x]>dd[y])
return lca[x][y]=getlca(ff[x],y);
return lca[x][y]=getlca(x,ff[y]);
}
void dp(int x,int fa)
{
int i;
for(i=1;i<=d[x];i++)
if(c[x][i]!=fa)
dp(c[x][i],x);
for(i=1;i<=d[x];i++)
if(c[x][i]!=fa)
dfs2(c[x][i],x,i,0);
memset(ns,0,sizeof ns);
int cx,cy,cs;
for(i=l.h[x];i;i=l.t[i])
{
if(l.v[i].first==x)
{
cx=0;
cy=e[l.v[i].second];
cs=g[l.v[i].second];
}
else if(l.v[i].second==x)
{
cx=e[l.v[i].first];
cy=0;
cs=g[l.v[i].first];
}
else
{
cx=e[l.v[i].first];
cy=e[l.v[i].second];
cs=g[l.v[i].first]+g[l.v[i].second];
}
cs++;
if(cx>cy)
swap(cx,cy);
ns[cx][cy]=max(ns[cx][cy],cs);
}
for(i=1;i<=d[x];i++)
if(c[x][i]!=fa)
{
cx=0;
cy=i;
cs=f[c[x][i]][(1<<d[c[x][i]])-1];
ns[cx][cy]=max(ns[cx][cy],cs);
}
int j,k;
for(i=0;i<=d[x];i++)
for(j=0;j<=d[x];j++)
if(ns[i][j])
{
int s=0;
if(i)
s|=1<<(i-1);
if(j)
s|=1<<(j-1);
for(k=0;k<(1<<d[x]);k++)
if(!(k&s))
f[x][k|s]=max(f[x][k|s],f[x][k]+ns[i][j]);
}
}
void solve()
{
memset(d,0,sizeof d);
int n;
scanf("%d",&n);
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
lca[i][j]=0;
for(i=1;i<=n;i++)
for(j=0;j<(1<<10);j++)
f[i][j]=0;
l.clear();
int x,y;
for(i=1;i<=n-1;i++)
{
scanf("%d%d",&x,&y);
c[x][++d[x]]=y;
c[y][++d[y]]=x;
}
dfs(1,0,1);
int m;
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
l.add(getlca(x,y),pii(x,y));
}
dp(1,0);
int ans=0;
for(i=1;i<=n;i++)
ans=max(ans,f[i][(1<<d[i])-1]);
printf("%d\n",ans);
}
int main()
{
#ifdef DEBUG
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
int t;
scanf("%d",&t);
while(t--)
solve();
return 0;
}
【BZOJ4042】【CERC2014】parades 状压DP的更多相关文章
- BZOJ 4042 Luogu P4757 [CERC2014]Parades (树形DP、状压DP)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4042 (Luogu) https://www.luogu.org/prob ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
- HDU 1074 Doing Homework (状压dp)
题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...
- 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP
[BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...
随机推荐
- Bootstrap 栅格 样式 组件 插件
-----------------------------起先是我们造成习惯,后来是习惯造成我们. day 51 Bootstrap 官方网站: bootcss.com/ <!DOCTYP ...
- Python中的鸡肋多线程
作者:DarrenChan陈驰链接:https://www.zhihu.com/question/23474039/answer/269526476来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...
- H5 14-后代选择器和子元素选择器
14-后代选择器和子元素选择器 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- Streaming Principal Component Analysis in Noisy Settings
论文背景: 面对来袭的数据,连续样本不一定是不相关的,甚至不是同分布的. 当前,大部分在线PCA都只关注准确性,而忽视时效性! 噪声?数据缺失,观测有偏,重大异常? 论文内容: Section 2 O ...
- duxing201606的原味鸡树
链接 [http://murphyc.fun/problem/4011] 题意 描述 众所周知,duxing哥非常喜欢原味鸡.众所周知,原味鸡是长在原味鸡树上的. duxing哥因为是水产巨子,所以就 ...
- Verilog语法遗漏点
1 关于参数定义 Parameter:parameter只能定义在端口生命的前面,如 Input[whith:0] a; Parameter whith=4; 这样的参数定义出现在声明的后面会报错 2 ...
- Magic Stones CodeForces - 1110E (思维+差分)
E. Magic Stones time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- PAT L2-020 功夫传人
https://pintia.cn/problem-sets/994805046380707840/problems/994805059118809088 一门武功能否传承久远并被发扬光大,是要看缘分 ...
- PHP常见错误汇总
日常开发和调试的时候,经常会遇到一些错误,光怪陆离的不知所以,所以,特此将错误汇总一下,借鉴!!! 1. 原因分析: 一般可能是该文件出现了问题,检查一下代码和格式,是否出现开始的地方出现了空格,或 ...
- js 通过url获取里面的参数值
场景描述:当我们从一个页面要带有一两个值跳转到另一个页面,另一个页面要使用这些参数的时候,我们就需要通过js获取这些参数啦. 先贴上代码: function getQueryString(name) ...