CSP2019前停课做题练习

「AMPPZ2014」Petrol

首先对于每一个点 \(x\) 预处理出 \(nr[x]\)\(dis[x]\),分别表示离 \(x\) 最近的加油站以及该段距离。
这个过程可以用多源 \(\text{Dijkstra}\) 处理。
然后对于每一条原图中的边 \((u, v, w)\)\(nr[u]\ne nr[v]\)
改为这样一条边:\((nr[u], nr[v], dis[u] + dis[v] + w)\)
然后只要离线用并查集维护一下连通性即可。


「AMPPZ2014」The Captain

直接连边的话边数肯定会爆炸,考虑减少边数。
我们画出坐标系,发现一个东西:
对于两个点 \(A,B\)\(|x_A-y_A|\) 可以经由由他们俩之间的若干点取到,\(y\) 同理。
所以我们只需要先把所有点分别按照 \(x\)\(y\),相邻两点之间连边即可。


「CF1037D」Valid BFS?

考虑直接模拟 \(\text{BFS}\) 的过程。
对于每一个节点的儿子,先遍历在输入序列中靠前的,判断 \(\text{BFS}\) 是否匹配即可。


「luogu1613」跑路

对于所有可以用 \(2^k\) 形式表示的 \(dis(i,j)\),将\(i,j\)之间的 \(dis\) 置为 \(1\),可以用倍增 \(\text{Floyd}\) 实现。
然后直接 \(\text{Floyd}\) 最短路即可。


「NOIP2017」逛公园

考虑 \(\text{DP}\)
\(f[u][k]\) 表示从 \(u\)\(n\) 走过不超过 \(Mindis(u, n) + k\) 距离的方案数。
转移方程为:\(f[u][k] = \sum{f[v][k + Mindis(u,n) - Mindis(v,n) - dis(u,v)]}\)
\(Mindis\) 可以预处理。
无解的情况直接在记搜的时候把 \(-1\) 传上去。
最后输出 \(f[1][k]\) 即可。


「NOIP2013」货车运输

首先 \(\text{Kruskal}\) 一下,构造出一棵森林。
并查集还要用来判断连通性。
倍增 \(\text{LCA}\) 的时候顺便维护一下路径最小值即可。


「CF891C」Envy

考虑最小生成树的几个性质:

  • 所有最小生成树中边权相等的边的条数相等
  • 在任意一颗最小生成树中,边权相等的边所联通的点集一定

那么我们考虑把边权相等的边单独拿出来考虑。
每次把并查集恢复到加边前的状态,然后再判断这些边加进去会不会形成环即可。

PS. 恢复并查集时,可以考虑求出每一条边在 \(\text{Kruskal}\) 的过程中,将要被加入时两端点所在联通块。


「CF241E」Flights

首先对于所有不属于任何一条路径上的边,它的权值是任意的。
对于所有在路径上的边 \((u,v)\) 满足 \(1\le dis_v-dis_u\le2\)
差分约束即可。


「POI2010」Bridges

首先二分答案,然后在所有边权小于二分值的边和所有点组成的图中判欧拉回路。
由于可能出现混合图,所以要用到网络流。
把所有无向边钦定一个方向,那么原图就是一个有向图。
那么存在欧拉回路的充要条件就所有点的入度等于出度且图联通。
我们考虑把点 \(x\) 的入度与出度之差记作 \(\Delta x\)
那么对于所有的定向后的无向边 \((u,v)\),连一条从 \(u\rightarrow v\) 的容量为 \(1\) 的边。
表示将该条边反向可以使 \(\Delta u += 2,\Delta v -= 2\)
然后考虑对于所有度数差小于 \(0\) 的点 \(x\),连一条 \(s \rightarrow x\) 的容量为 \(\frac{|\Delta x|}{2}\) 的边。
表示 \(x\) 需要操作这么多次,使得 \(\Delta x\) 达到 \(0\)。小于零的情况同理。
最后判断是否满流即可。


「NOIP2018」赛道修建

一眼先二分(上界树的直径,下界最小边权),然后再考虑 \(\text{DP}\)
对于当前节点 \(u\),在它的所有儿子中分别返回一条匹配不完的长度最大的路径 \(Max\)
若该路径长大于二分值,直接修一条,不然丢进 \(\text{multiset}\) 里面。
对于 \(\text{multiset}\) 里的元素每次贪心的找出尽可能大的一条与最小的匹配,若找不到则用来更新 \(Max\)
\(check\) 函数里面返回 \(ans\ge m\),最后输出答案即可。

猜你喜欢

转载自www.cnblogs.com/zsbzsb/p/11672535.html