感觉长脑子了。


考虑在路线两端点的 \(lca\) 计算贡献,那么线段可以分两类:

  1. \(u\) 为 \(v\) 祖先。
  2. \(u,v\) 互不为祖先。

设 \(dp_i\) 表示只考虑 \(i\) 子树内的路线时的答案。

引理:若插入一条以 \(i\) 为 \(lca\) 的路径会使以 \(i\) 的儿子为 \(lca\) 的路径数量减少,一定不优。

正确性显然。根据这一条性质,我们就可以不用维护儿子中具体的路径了,只需要维护 \(f_{i,j}\) 表示以 \(i\) 为根的子树中,能不能满足 \((i,j)\) 上没有边被使用且不使答案减小。

首先 \(i\) 的所有 \(1\) 类路径,能插就插,一定最优,没他一定不优。

其次剩下部分就是一般图最大匹配,\(dfs\) 即可,时间复杂度 \(O(sn^22^{sn})\)。

考虑维护 \(f_{u,w}\)。假如 \(w\) 在 \(u\) 的儿子 \(v\) 的子树中,那么 \(f_{u,w}=1\) 时,必定满足 \(f_{v,w}=1\)。那么问题转化为 \((u,v)\) 被占用是否是达成最优解的必要条件。这里的判断分两种情况:

  1. 能插入 \(1\) 类边。这种情况肯定被使用了。
  2. 能插入 \(2\) 类边。这种情况直接强制他不能插在这里,然后再跑一般图最大匹配,看答案有没有变化即可。

时间复杂度 \(O(tsn^32^{sn}n)\),由于题目保证 \(sn\le 10\),而且一般图最大匹配根本跑不满,因此可以通过。

#include<bits/stdc++.h>
#define pp pair<int,int>
using namespace std;
const int N=1005;
int t,n,m,dp[N],vs[N],f[N][N];
int idx[N][N],ft[N][15],dep[N];
vector<int>g[N],ux[N],uv[N];
vector<pp>xy[N],vw[N];
int maxp(int nm,int k,int nw){
if(nm==g[k].size()) return nw;
int re=maxp(nm+1,k,nw),x=g[k][nm];
if(!vs[x]) for(int i=0;i<xy[k].size();i++){
int v=vw[k][i].first,w=vw[k][i].second;
int l=xy[k][i].first,r=xy[k][i].second;
if(v>w) swap(l,r),swap(v,w);
if(v!=x||vs[w]||!f[v][l]||!f[w][r]) continue;
vs[v]=vs[w]=1,re=max(re,maxp(nm+1,k,nw+1)),vs[v]=vs[w]=0;
}return re;
}void getf(int x,int fa,int u,int v,int id){
f[u][x]=(id&f[v][x]);
for(auto y:g[x])
if(fa!=y) getf(y,x,u,v,id);
}void dfs(int x,int fa){
sort(g[x].begin(),g[x].end());
for(auto y:g[x])
if(fa!=y) dfs(y,x),dp[x]+=dp[y];
for(int i=0;i<ux[x].size();i++){
int y=ux[x][i],v=uv[x][i];
if(f[v][y]&&!vs[v]) vs[v]=1,dp[x]++;
}int ans=maxp(0,x,0);
for(auto y:g[x]){
if(y==fa) continue;
if(vs[y]){getf(y,x,x,y,0);continue;}
vs[y]=1;int re=maxp(0,x,0);vs[y]=0;
getf(y,x,x,y,re==ans);
}dp[x]+=ans,f[x][x]=1;
}void get_fa(int x,int fa){
ft[x][0]=fa,dep[x]=dep[fa]+1;
for(int i=0;i<14;i++)
ft[x][i+1]=ft[ft[x][i]][i];
for(auto y:g[x])
if(y!=fa) get_fa(y,x);
}int lca(int x,int y){
for(int i=14;~i;i--)
if(dep[ft[x][i]]>=dep[y]) x=ft[x][i];
if(x==y) return x;
for(int i=14;~i;i--)
if(ft[x][i]!=ft[y][i]) x=ft[x][i],y=ft[y][i];
return ft[x][0];
}void get_id(int x,int lst){
if(x==1) return;
idx[ft[x][0]][lst]=x;
get_id(ft[x][0],lst);
}void solve(){
for(int i=1;i<=n;i++){
g[i].clear(),ux[i].clear(),uv[i].clear();
xy[i].clear(),vw[i].clear(),dp[i]=vs[i]=dep[i]=0;
for(int j=1;j<=n;j++) f[i][j]=idx[i][j]=0;
for(int j=0;j<15;j++) ft[i][j]=0;
}cin>>n;
for(int i=1,x,y;i<n;i++)
cin>>x>>y,g[x].push_back(y),g[y].push_back(x);
cin>>m,get_fa(1,0);
for(int i=1;i<=n;i++) get_id(i,i);
for(int i=1;i<=m;i++){
int x,y;cin>>x>>y;
if(dep[x]<dep[y]) swap(x,y);
int lc=lca(x,y);
if(lc==y){
uv[y].push_back(idx[y][x]);
ux[y].push_back(x);continue;
}vw[lc].push_back({idx[lc][x],idx[lc][y]});
xy[lc].push_back({x,y});
}dfs(1,0),cout<<dp[1]<<"\n";
}int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--) solve();
return 0;
}

[CERC2014] Parades 题解的更多相关文章

  1. BZOJ 4042 Luogu P4757 [CERC2014]Parades (树形DP、状压DP)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4042 (Luogu) https://www.luogu.org/prob ...

  2. BZOJ4042 : [Cerc2014] parades

    设f[x]为x子树里能选的最多的路径数,h[x]为x子树里往上走的点的集合,且不与x子树内的最优解冲突 首先f[x]=sum(f[son]) 若h[son]与x可以直接匹配,则匹配上,f[x]++ 然 ...

  3. LuoguP4759 [CERC2014]Sums 题解

    Content 给定 \(t\) 组数据,每组数据给定一个数 \(n\),判断 \(n\) 是否能够分解成连续正整数和,能的话给出最小数最大的方案. 数据范围:\(1\leqslant n\leqsl ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. 【BZOJ4042】【CERC2014】parades 状压DP

    题目大意 给你一棵\(n\)个点的树和\(m\)条路径要求你找出最多的路径,使得这些路径不共边.特别的,每个点的度数\(\leq 10\). \(n\leq 1000,m\leq \frac{n(n- ...

  6. bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)

    bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp) bzoj Luogu 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符 ...

  7. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  8. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  9. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  10. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

随机推荐

  1. datagridview点击列头对当前列进行排序的功能无效

    DataGridView 的默认行为是支持通过单击列头对列进行排序,但在以下情况下可能会取消该功能或无法使用: 1. 绑定的数据源不支持排序 如果 DataGridView 的数据源是绑定到一个不支持 ...

  2. 使用ProWindow时,控制按钮状态的说明

    在Pro SDK中,提供了一个默认的窗口基类,ProWindow Class,提供了基础的窗体样式,可供扩展和调用. 有网友问我,在使用时,会发现窗体右上角的控制按钮,有时会没有按照自己的预期显示. ...

  3. JAVA开发规范v1.0

    01-中铜国贸JAVA开发规范v1.0 一.编程规约 (一)命名风格 [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例:_name / _name / $Obje ...

  4. docker - 将几个目录复制到另一个目录

    您如何将多个目录复制到Docker中的目标目录?我不想复制目录内容,而是复制整个目录结构.COPY和ADD命令复制目录内容,展平结构,这是我不想要的.也就是说,如果这些是我的来源: . ├── a │ ...

  5. Spring MVC 中 DefaultServletHandlerConfigurer

    <mvc:default-servlet-handler/> 这个Spring MVC xml文件的属性,主要是处理web项目的静态文件问题. 每次请求过来,先经过 DefaultServ ...

  6. JVM实战—1.Java代码的运行原理

    大纲 1.Java代码到底是如何运行起来的 2.JVM类加载机制的一系列概念 3.JVM中有哪些内存区域及各自的作用 4.JVM的垃圾回收机制的作用 5.问题汇总 1.Java代码到底是如何运行起来的 ...

  7. Qt编写物联网管理平台32-表格数据

    一.前言 用表格来展示采集到的数据,是很多组态系统中最常见的方法,一个表格能够展示的数据特别多,在本系统中,默认做的也是通过表格的形式来展示数据,目前是将所有的设备放在一个表格中,后期可能按照不同控制 ...

  8. 关于Qt中的qss样式表需要注意的坑

    关于QSS要注意的坑. qss源自css,相当于css的一个子集,主要支持的是css2标准,很多网上的css3的标准的写法在qss这里是不生效的,所以不要大惊小怪. qss也不是完全支持所有的css2 ...

  9. Qt编写的项目作品34-雷达模拟仿真工具(雨田哥作品)

    一.功能特点 支持音频频谱显示. 支持任意随机添加模拟点. 支持自定义添加模拟点. 支持方位.航向角.距离.速度.目标体真实图自定制. 支持危险区域范围显示. 支持激光发射模拟. 支持雷达图放大缩小显 ...

  10. MySql中的driverClassName、url

    在Java桌面开发或者Java Web开发(基于SSM框架)配置MySQL数据源时,driverClassName属性如果填错了,会导致了这一系列错误.归结其原因就是 mysql-connector- ...