UESTC暑假前集训—图论-解题报告
A - 迷宫
给出一个带权有向图,翻转一条边的代价是其权重,求出翻转边后图中无环的最小代价
二分
拓扑判环
一开始只能想到要让图中没有环,但是想不清楚怎么操作,于是等到题解emmmm
考虑对于要改变的边,相当于删去之后反向加回来,那么代价就是边里面权值最大的
二分权值,权值越大的可以改变的边越多,二分最少的代价使得不存在环即可
1 | int n,m; |
B - oydy的征途I
给定一个带权无向图,求出最小生成树但是其中某一条边可以0权值,已经可能的最小权值和的总数
最小生成树
先求出最小生成树,把最大权的边删去之后,求剩下的边的连通性
时间复杂度$ O(mlogm) $
1 | int n,m; |
C - oydy的征途II
给定一个有向图,如果存在欧拉路径的话就输出最小字典序的欧拉路径
欧拉路径
手写栈
WA8 WA15 TLE28
我就是个弟弟
WA8是因为出入栈顺序的问题,WA15是因为地点直接设置成了1,TLE是因为遍历的是邻接表,所以如果存在2e6个1的自环的情况下时间复杂度会达到$ O(m ^ 2) $
改成用栈删边之后,时间复杂度降低到$ O(m) $
1 | vector<Edge> G; |
D - oydy的征途III
给定一个带权无向图,从第一个点开始,求出到一个序列的点的最短距离
最短路
树链剖分
`
除去树之后多出来的边比较少,所以先把树拿出来求树上距离,再跑出剩下30条边的端点到其他点的最短路
每次询问取经过剩下的边上的端点距离和树上距离
树上距离我直接扒了一棵生成树下来树剖
时间复杂度$ O(30(n + m)logn + nlogn) $
1 | struct Node{ |
E - 变色龙
给定$ n $个点,$ m $条边,每条边都有颜色,求出从1号点到$ n $号点所需要变换颜色最多的次数
以边代点
拆点
一开始能想到的只有将一条边经过一个点到另外一条边考虑成从一个点到另外一个点,如果颜色相同的两个点的权值就是0,反之为1
但是遇到菊花图的时候空间复杂度是$ O(m^2) $,如不存边的话时间复杂度又会变成$ O(m^2) $
于是看了题解知道要拆点QAQ,用map
把空间复杂度降到$ O(m + n) $,跑一遍dijkstra求最短路再除2
1 | int n,m; |
F - zh吃饭
给出一个有向图,求经过每个边权后到达某个点集内的点总的最大的边权和
tarjan
缩点
tarjan求强连通分量直接缩点重新建图跑最长路,找了以前写的缩点的代码直接粘上来嘿嘿嘿
1 | int n,m,tmp,s,p; |
G - hqf吹泡泡
给定$ n $个点,有$ m $ 种连接关系,表示$ u $、$ v $两个点连接所需要的代价是$ w $,要求最少的将所有点连接成$ k $块所需要的代价
最小生成树
本来能1A的一个题结果手太抖了错失一血。。
直接用最小生成树的算法,每连接一次就减去当前块数的数量,然后减到k的时候结束输出答案
时间复杂度$ O(nlogn) $
1 | ll n,m,k,tt = 0; |
H - 毁灭东湖计划
给定一个有向图,求出从1到n的最大流量
网络瘤
网络瘤板题,抄了紫书的EK板子(逃
1 | vector<Edge> G; |
I - cxx仙女下凡
给出一个有向图,求出其中从$ s $到$ t $第$ k $短的路径长度
k短路
A*
k短路模板题,先spfa求出其他点到t最短的路径长度,用A*的估价函数进行估值然后拓展,第k次经过的时候就是第k短路
1 |
|
J - cxx守株待兔
给出一个二分图,求最大匹配
匈牙利
网络瘤
把二分图的两边加一个超级源点和一个超级汇点,然后跑一下网络流(
一开始以为EK会被卡就套了Dinic的板子,结果试了一下EK也可以过。。
1 | vector<Edge> G; |
K - cxx承包鱼塘
给出一个带权无向图,求出最多免费k条边后$ s $到$ t $的最短距离
分层图
DP
在dijkstra
里面加一个免费这条边的情况下的最短距离,然后类似于动态规划搞一下
时间复杂度$ O((m + n)logn) $
1 | int n,m,k,s,t; |
L - cxx的压岁钱
给定n个电视所需要花费的代价,以及选取某几个电视就可以得到的利润,求出最大的利润
最大权闭合子图
网络流
抽象一下,就是选取某一个结点,那么它的后继也要被选取
看到题目的时候满脸网络流,但是不知道建模是怎么建的emmm
建模的就是将选取的后继的这一边的容量设为无穷大,源点连接的所需要选取的容量为对应利润,后面汇点连接的容量为对应的代价
跑出最大流,然后用$ \sum c$减去最大流
1 | vector<Edge> G; |
M - 洁姐姐带我找工作
给出每两个公司的给出的offer数量关系,求出最少的offer数
dfs
并查集
拓扑排序
既然是图论,一开始想到的是建一个有向图表示大于小于关系,但是等于关系想不清楚
当时晚上放题的时候还想到了差分约束emmmm
然后想到用并查集将等于的点缩在一个点上,但是排序对应点的权值的处理有点问题
后来想到的是并查集
+ 拓扑排序
,但是拓扑排序排不出来(我是辣鸡
那么把大于的建图反向过来,这样方便从1开始处理权值,然后每次选取入度为0的点开始dfs
求出每个点对应的深度就是权值,然后每次递归到某一层如果权值已经不为0了就选择最大的一个深度作为权值
最后把权值全部加起来就是答案
1 | int fa[1007],siz[1007],in[1007],vis[1007],w[1007]; |
N - 洁姐姐带我上分
jjjj一次能带$ k $个人上段位,每次jjjj不在的情况下每队cp都不能在一起,jjjj可以随意地上段位或者下段位,求出最少的让所有人都到高段位的代价
DAG
DP
状态压缩
这题也是康题解做的
用二进制整数表示当前某个段位的状态,然后筛出合法的数据,按照条件得到合法转移条件连边
最后跑一遍最短路。。
合法状态:末位为0的同时不能有一对cp的位置同时为1
合法转移:1的个数少于等于$ k $ 、状态转移的变量末位是1、同时两个转移状态之间的最大值减去状态变化值是两个转移状态的最小值
1 | struct Node{ |
O - 洁姐姐带学画画
给出n个点,已经它们在三维空间中的坐标,求出生成树,并且每条线段的连接的两个点的高度差之和比上水平距离之和最小
最小生成树
prim
牛顿迭代
01分数规划
用一个表达式表示一个最小生成树,权值总和为
$$
x_1a_1 + x_2a_2 + … +x_na_n
$$
$x_i$表示选取或者不选取
令得到的答案为$ans$
那么有
$$
\frac {\sum x_ih_i}{\sum x_id_i} >= ans \
移项,有 \sum x_ih_i >= ans\sum x_id_i \
展开,x_1(h_1 - ansd_1) + x_2(h_1 - ans * d_2) + … + x_n(h_n - ansd_n) >= 0
$$
可以进行二分判断得到的ans是否使得最小生成树为0即可,
除了使用二分,还可以使用牛顿迭代法更新答案直到$x >= xx$,也就对应二分上面式子为0的时候
1 | int n; |