首页 > 其他分享 >CF 838 E

CF 838 E

时间:2024-10-12 18:48:27浏览次数:10  
标签:int 838 al CF 坏人 ans 警察 sim

这一题最重要的是设计状态。

首先,坏人不可能不被抓到,因为你再怎么说都可以一个一个抓,这样每一次逼到叶子节点。

一个显然的状态是 \(dp_{s,(a_1\sim a_m)}\) 代表警察在 \(s\),坏人在 \(a_1\sim a_m\) 的最小时间,但是显然会爆掉。

  • 性质一:因为坏人速度无限大,所以警察来抓他们的时候一定呆在叶子节点。

如果不在叶子节点,一定可以省去时间。

  • 性质二:坏人在哪一个节点不重要,只和警察的相对位置重要。

这也是因为坏人的速度是无限大。

所以现在有另一个状态 \(dp_{u,(c_{1}\sim c_{sz})}\) 代表警察在 \(u\),在 \(1\sim sz\) 个 \(u\) 的子树内分别有 \(c_1\sim c_{sz}\) 个坏人。但是还是会爆炸。

分析一下爆炸的本质。因为我们是模拟警察从一个节点到另一个节点,所以相对方位有很多种。但是其实因为坏人速度无限大,其实警察可以看作是从一个边到另一个边,因为坏人可以“预判”警察下一步是什么(可以想象为,警察在 \(u\rightarrow v\) 中间时定住了,\(u,v\) 两边的坏人分别可以随意交换顺序)。

因此设计状态:\(dp_{u,v,al,c}\) 表示目前警察 \(u\rightarrow v\) 这个方向,警察面向的子树内有 \(c\) 个坏人,现在一共还剩 \(al\) 个坏人。

考虑转移:枚举下一步,那么新的时间其实就是坏人的所有排列的下一步得到的最小时间。这个可以用一个背包求得。

代码很好写。

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 55;

int n,s,f[N][N][N][N],d[N][N],m,x[N],cnt,vis[N]; 
vector<int> e[N];

void dfs(int u,int fa){
	cnt+=vis[u];
	for (auto v : e[u]){
		if (v^fa) dfs(v,u);
	}
}

int sol(int u,int v,int al,int in){
	auto &ans=f[u][v][al][in];
	if (~ans) return ans;
	if (!al) return ans=0;
	if (e[v].size()==1) return ans=sol(v,u,al-in,al-in)+d[u][v];
	int g[N];
	g[0]=1e9;
	for (int i=1; i<=al; i++) g[i]=-1e9;
	for (auto p : e[v]){
		if (p^u){
			for (int i=in; i; i--){
				for (int j=1; j<=i; j++){
					g[i]=max(g[i],min(g[i-j],sol(v,p,al,j)+d[u][v]));
				}
			}
		}
	}
	return ans=g[in];
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n;
	for (int i=1; i<n; i++){
		int u,v,w;
		cin>>u>>v>>w;
		e[u].push_back(v);
		e[v].push_back(u);
		d[u][v]=d[v][u]=w;
	}
	cin>>s>>m;
	for (int i=1; i<=m; i++){
		cin>>x[i];
		vis[x[i]]++;
	}
	memset(f,-1,sizeof f);
	int ans=1e9;
	for (auto u : e[s]){
		cnt=0;  
		dfs(u,s);
		ans=min(ans,sol(s,u,m,cnt));
	}
	cout<<ans<<"\n";
	return 0;
}

标签:int,838,al,CF,坏人,ans,警察,sim
From: https://www.cnblogs.com/SFlyer/p/18461255

相关文章

  • CF1746F Kazaee(随机化哈希)
    真的做不来这种题怎么办/ll题意给定\(n\)个数,\(q\)次操作:单点修改一个数的值。查询区间内所有数的出现次数是否均为\(k\)的倍数。\(n,q\le3\times10^5\)。分析一眼看上去只能带修莫队,而且常数还巨大无比。这种随机化哈希题一般是考虑一个必要不充分条件,但是充分的......
  • Day5 备战CCF-CSP练习
    题目描述给定\(n\)个不同的整数,问这些数中有多少对整数,它们的值正好相差\(1\)。输出格式输入的第一行包含一个整数\(n\),表示给定整数的个数。第二行包含所给定的$n$个整数。输出格式输出一个整数,表示值正好相差\(1\)的数对的个数。数据范围\(1≤n≤1000\),给定的......
  • 题解 QOJ5048【[ECFinal19K] All Pair Maximum Flow】
    题目描述给你一个\(n\)个点\(m\)条边的图,它是平面上的正\(n\)边形和一些对角线,节点按逆时针方向编号为\(1\)到\(n\)。对角线只可能在节点处相交。每条边有一个容量,求每个点对之间的最大流的和。\(n\leq200000,m\leq400000\)。solution做法每次找出边权最小的边\(......
  • VP CF975 div2
    前言别人说这场好,我就打打A简单模拟,分奇偶位置即可。B一开始没注意到端点的边界问题,后来分讨了一下,把端点和中间的点分开考虑即可C卡了1h的唐题,首先由于每堆中不能出现同种卡牌,所以答案一定<=n。当时想到这就开二分答案了,发现k=0的情况过不了,以为是特殊边界问题,直接特......
  • Day4 备战CCF-CSP练习
    题目描述有若干个任务需要在一台机器上运行。它们之间没有依赖关系,因此可以被按照任意顺序执行。该机器有两个CPU和一个GPU。对于每个任务,你可以为它分配不同的硬件资源:在单个CPU上运行。在两个CPU上同时运行。在单个CPU和GPU上同时运行。在两个CPU和GPU......
  • CF记录
    CF2019(div2,vp)比赛时网站炸了两次,有一次甚至连那个Oops的页面都没看到。/fnD.Speedbreaker做法比较多的一题。首先有一个带log但是比较简单的做法。求出\(a\)的后缀min\(s_i\)和前缀min\(p_i\),当出发点为\(x\)时,设\[b_i=\begin{cases}a_i=p_i,&i<x\\a_i=\m......
  • CF959F Mahmoud and Ehab and yet another xor task 题解
    题目传送门前置知识线性基解法将操作离线下来,并按\(\{l\}\)升序排序,接着顺序插入线性基并处理询问。对于未成功插入线性基的元素\(k\)一定能被线性基内选出若干元素得到。故在\(x\)能被表出的情况下,设\(1\siml\)中成功插入线性基的元素个数为\(siz\),对于剩下\(......
  • 十月初 AT/CF
    ABC374E最大最小值,想到二分,问题是怎么check。其实就是对两个种有价值有重量的物品,求达到规定价值的最小重量。只有两种物品,而且数据范围很小,考虑贪心。假设\(a\)的性价比较高,\(b\)的性价比较低,那么不可能选太多\(b\)。也就是如果能用\(a\)代替的就用\(a\)代替。所......
  • Day3 备战CCF-CSP练习
    Day3题目描述目前在一个很大的平面房间里有\(n\)个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要距离不超过\(r\)就能互相建立网络连接。除此以外,另有\(m\)个可以摆放无线路由器的位置。你可以在这些位置中选择至多\(k\)个增设新的路由器。你的......
  • 题解:CF1007D Ants
    题目传送门每只蚂蚁只走一对点肯定是不劣的,由此想到2-sat。限制条件是:若\((a,b)\)和\((c,d)\)两条链相交,则不能同时选。直接建图肯定是爆炸的。用树剖可以将\((a,b)\)这条链划分成\(O(\logn)\)个区间。因为同一条链的区间不交,限制条件变为若两个区间相交,则这两个点不......