图论
哈希表扁豆
此人不懒,但什么都没写
展开
-
【模板】线段树优化建图
Problem三种方案:v to u,v to [l,r],[l,r] to v。求单源最短路。Solution由于存在结点与区间内所有结点间的连边,可以考虑用线段树优化建图。具体来说维护两个线段树,线段树1表示有向边的终止结点,同时父亲连向儿子权为0;线段树2表示有向边的起始结点,同时儿子连向父亲权为0。两线段树的叶子结点间连无向边权为0(线段树1的叶子结点连向线段树2的叶子结点也可),表示同一结点自己和自己是连通的;对于任意有向边,线段树2连向线段树1,如图:Code#inclu原创 2022-04-20 21:10:04 · 987 阅读 · 0 评论 -
严格次小生成树
ProblemSolution做法与求非严格次小生成树类似(枚举非mst上的边来替换mst上的边)。需要同时维护最大边和严格次大边的倍增数组,不存在严格次大边的情况下需设为-inf,保证此次计算不会作为最终答案。关于严格次大边倍增数组的递推:取左右区间严格次大边的max,同时若左右区间的最大边不相等,两区间最大边的最小值。关于求树上两点间的严格次大边:假设待加入边权值为w,每次更新时若区间最大边<w,则用区间最大边更新,否则用区间的严格次大边更新。Code#include<i原创 2022-01-29 02:12:59 · 424 阅读 · 0 评论 -
非严格次小生成树
允许与mst权值和相等。#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;const int maxn=150,maxm=100005;const int inf = 1e9;int t,n,m,cnt,mst,logg[maxn],mx[maxn][15],pre[.原创 2022-01-29 00:55:48 · 409 阅读 · 0 评论 -
UVA10765 Doves and bombs(双连通分量)
Problem每个点的权为删除这个点后图中连通块的个数,求权值前m大的点。Solution求点-双连通分量,一个点的权值为总连通块数+该点出现在不同点连通分量的次数-1。该点出现在不同点连通分量的次数就是把该点删掉后原来所属的那个连通块会分裂成的连通块的个数。Code#include<iostream>#include<cstdio>#include<vector>#include<algorithm>#include<cst原创 2022-01-12 20:06:11 · 125 阅读 · 0 评论 -
UVA1201 Taxi Cab Scheme(二分图最小路径覆盖)
ProblemSolution可以转化成dag上的最小路径覆盖,dag的最小路径覆盖可以放在二分图上求。对于原图中的a->b,在二分图中连a->b’,dag上的最小覆盖=n-最大匹配(即左部中未匹配点数量,等价于所有覆盖的起点数量)。Code#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;co原创 2022-01-09 14:38:34 · 267 阅读 · 0 评论 -
UVA12083 Guardian of Decency(二分图最大独立集)
ProblemSolution原题要求选出的点中任意两点需至少满足一个条件,可以在四个条件都不满足的点间连边,所得图为二分图(一边男一边女),等价于求二分图的最大独立集。二分图最大独立集与最小覆盖集二分图最独立集大小=结点数-最大匹配(这里的最大匹配可以看成选择有边相连的两个点时要去掉其中一个,最大匹配数即为最小要去掉的点数,同时也是最小覆盖)。覆盖集:对于每条边,至少有一个点要被选中。独立集:对于每条边,至少有一个点不被选中。因此两者互补。最小覆盖集大小=最大匹配的大小。Code#原创 2022-01-09 13:59:36 · 301 阅读 · 0 评论 -
稳定婚姻问题(UVA1175 Ladies‘ Choice)
Problem在一个盛大的校园舞会上有 n 位男生和 n 位女生,每人都对每个异性有一个排序,代表对他们的喜欢程度。你的任务是将男生和女生一一配对(每人恰好有一个舞伴),使得男生 u 和女生 v 不存在以下情况:(1)男生 u 和女生 v 不是舞伴;(2)他们喜欢对方的程度都大于喜欢各自当前舞伴的程度。如果出现了(2)中的情况,他们可能会擅自抛下自己的舞伴,另外组成一对。Gale-Shapley算法每一轮每一个尚未订婚的男士向自己当前好感度最高且还未向其求过婚的女士求婚,然后女士在向她求婚的人中选择原创 2021-12-31 09:48:51 · 299 阅读 · 0 评论 -
UVA1411 Ants
无原创 2021-12-29 12:01:03 · 255 阅读 · 0 评论 -
KM算法及应用整理
Kuhn-Munkers算法思想设立左右顶标l,规定l(u)+l(v)>=w(u,v),相等子图是包含满足l(u)+l(v)=w(u,v)所有边的生成子图,相等子图的完美匹配是原图的最大权完美匹配。通过调整顶标,贪心地将边权最大的边变成相等边,逐渐扩大相等子图。算法流程初始化顶标。(一般将左顶标设为最大边权)用匈牙利算法寻找可行匹配。若未找到则修改顶标。重复以上过程直至相等子图完备。最大权完美匹配模板通过状态延续使时间复杂度降至n3。vx,vy为单次标记的左右部的点,px,原创 2021-12-28 16:55:55 · 753 阅读 · 0 评论 -
魔法猪学院(A*面向数据版)
新数据卡了A的空间复杂度,但在本题中A有几个值得优化的地方。题目要求到达目标就结束,因此到达终点后不再对外扩展。‘可以预设一个k,k=mx/dis[n],表示k短路内一定能确定答案。#include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <queue>using namespace std;const int maxn = 50.原创 2021-09-27 17:36:34 · 126 阅读 · 0 评论 -
【模板】无向图三元环计数
Problem给定一个 n 个点 m 条边的简单无向图,求其三元环个数。n<=1e5,m<=2e5。Solution枚举三个点O(n3),枚举临边O(m2),枚举点及其对边O(nm)都会T,根本原因在于任何一个简单三元环都会被枚举多次。于是我们可以得到一个直观的优化思路:避免对环的重复枚举。如果是有向图,对于一类子图的计数是不会出现重复统计,因此可以可以按照一个统一的规则将无向图转换成有向图?方法:对于一条边的两个端点,度小的连向度大的,度数相同的情况下编号小的连向编号大的,这原创 2021-09-18 17:49:24 · 367 阅读 · 0 评论 -
欧拉道路 (模板)
Problem求有向图字典序最小的欧拉道路,没有输出“No”P7771 【模板】欧拉路径Solution欧拉道路:一笔画,特别地,起点与终点相同时称为欧拉回路。有向图欧拉道路:一般情况:只存在一个出度比入度大一的点作为起点,只存在一个入读比出度大一的点作为终点,其余点入度与出度相等。特殊情况:欧拉回路,所有点的入度与出度相等。其余情况均不存在欧拉道路。求字典序最小的欧拉道路:对所有点所能到达的点按照字典序排序,然后dfs,注意,直接按照dfs序输出是不对的,因为一般情况下要保证终点最后到达原创 2021-09-18 16:44:24 · 528 阅读 · 0 评论 -
二分图最小顶点覆盖
Problem方格上有一些给定点,每次可以覆盖一行或者覆盖一列,求覆盖所有给定点的最小次数。Solution将行最为左边的点,列作为右边的点,对于每个给定点行向列连边,二分图最大匹配即为答案。合法性:最大匹配的基础上所有的点一定会被覆盖。最优性:...原创 2021-09-03 17:01:26 · 283 阅读 · 0 评论 -
UVA1663 净化器 Purifying Machine(二分图匹配)
ProblemSolution得到了二分图匹配的提示才想到怎么做,还是太笨了 。一个模板可能匹配一个串或两个串,要让匹配两个串的模板尽可能的多,建立二分图,能用一个模板匹配的串连边,设最大匹配为ans,给定的模板集合所能匹配的串数为ele,答案即为ele-ans+ans/2。位运算小技巧:x第y位置0: x|=(1<<y);x第y位置1:x&=~(1<<y)。Code#include<iostream>#include<cstring&g原创 2021-08-31 20:15:40 · 179 阅读 · 0 评论 -
【模板】最小斯坦纳树
ProblemSolution状压dp,dp(i,s)表示i为根包含点集s的最小权值和。用floyd预处理出两点间的最短路,dijkstra或spfa也可。分两种情况转移:i度数为1和i度数不为1。i度数为1:枚举相邻点j,dp(i,s)=min(dp(i,s),dp(j,s)+dis(i,j))。i度数不为1:枚举子集,dp(i,s)=min(dp(i,sub)+dp(i,s^sub))。注意转移状态的次序,从状压dp的角度考虑也有别的转移方法,不过这种最右,时间复杂度n2 * 2k+n原创 2021-08-30 17:39:29 · 161 阅读 · 0 评论 -
UVA1668 Let‘s Go Green
Problem求最少用多少边能覆盖整个树,给出每条边被覆盖的次数Solution挺巧妙的逆向思维,最大值就是边权和,然后尽可能对每个点周围的边合并,根据周围一圈的最大值与一圈和的关系计算并掉多少。Code#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;const int maxn=1e5+5;in原创 2021-08-23 17:00:31 · 121 阅读 · 0 评论 -
D - Hangar Hurdles(kruskal重构树+树上倍增)
Problem给出n*n由.和#组成的网格,q组询问,每组询问给出起点和终点,求每次将箱子从起点推向终点的最大箱子边长(障碍不能在箱子所占范围内)。n<=1000,q<=300000。4s,512M。Solution一开始想用floyd预处理,然后O(1)查询,但点的数量级为1e6,会T。由此题可推出的小结论:当最短路问题的距离定义为路径瓶颈时,答案等价于最值生成树上路径的最值。预处理求出以每个点为中心的箱子最大边长,一次bfs或者二维前缀和+二分,bfs时从障碍往外bfs。正原创 2021-08-17 19:16:19 · 178 阅读 · 0 评论 -
kruskal重构树 笔记
建树在做生成树的过程中每次加入一条边时引入一个新的节点作为两个点的父亲(并查集代表元素),新引入的结点点权为这条边的边权。(蓝色为生成树,红色为重构树)一点性质树上的每条链具有单调性(与排序有关);原来图中的结点全部对应重构树中的叶子结点;应用lca(u,v)的点权为生成树上u到v路径上边的最值(与排序有关)。求从u出发只经过边权不超过x的边能到达的结点:在边权升序排序的kuaskal重构树中找到深度最小的点权不超过x的点(倍增找),其子树(u在其子树中)内所有叶子结点即为所求。原创 2021-08-17 19:12:02 · 119 阅读 · 0 评论 -
树上倍增求LCA
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int cnt,n,m,s,last[500005],f[500005][22],dep[500005],logg[500005];struct edge{ int next,v,u;}e[1000010];inline void inserts(int u,int v){ cnt++;原创 2020-11-03 20:26:59 · 100 阅读 · 0 评论 -
K - TV Show Game
Problem一群人猜气球,每个人猜三个,每个气球有红蓝两种颜色,求是否存在让每个人至少猜对两个气球的气球颜色方案。Solution2-sat模板题,场上没往这方面想。2-sat问题解法+证明+模板2-sat解决的什么问题?满足必须满足的约束条件:选了一些必须选另一些。本题中对于一个人来说猜错了某个气球则意味着其它两个气球必须猜对,根据此约束条件建图即可:2i表示第i个气球为红色,2i+1为蓝色,枚举每个人猜错的那个气球建图。Code#include <iostream>#i原创 2021-08-15 17:49:49 · 297 阅读 · 0 评论 -
E - Equidistant(bfs)
Problem给定一棵树和树上一些点,求任意一个树上到所有给定点距离相等的点。Solution直接对所有选中的点往外bfs,但是需要一些超越常数的优化,要不然又TLE又MLE。记录所有选出的点到每个点的最短距离,记录选中的点在最短距离下到达其他点的次数,只在第一次访问的时候(最短距离)push(这样保证了每个点只进队一次),相等的时候更新最短距离下到达的该点的所选中点的数量。注意检查极限情况是否能算对。Code(写的很乱)#include <iostream>#include原创 2021-08-14 20:33:42 · 178 阅读 · 0 评论 -
J - Just the Last Digit
Problem给定两个点间的路径数的各位,还原整张图,矩阵表示。只可能编号小的点连向编号大的点。Solutioni到j是否有直接相连取决于所有的k to j(i<k<j且i与k直接相连)的路径数的和是否小于i to j的路径数从大到小枚举i,从小到大枚举j,同时维护与i直接相连的点即可。Code#include <iostream>#include <cstdio>using namespace std;const int maxn=520,mod=10;原创 2021-08-14 17:07:59 · 140 阅读 · 0 评论 -
【2019 NWERC - D 】Disposable Switches【★★★★】
Problem【★★★】边的权值为l/v+c,其中已知l,求那些点不可能成为1 to n最短路上的点。v>0,c>=0,v与c是确定的数。Model Building【★★★★】spfa+单调栈+dfs。Solution【★★★★】dis[i][j]表示经过j条边到达i的只考虑l下的最短路,经过k条边到达n的最短路为dis[n][k]/v+k*c,以c的大小为x轴,1 to n的最短路为y轴建立平面直角坐标系(v只不影响直线与y轴交点的相对位置,因此也不影响直线件交点的相对位置):原创 2021-08-06 10:40:34 · 210 阅读 · 0 评论 -
K - Birdwatching
Problem给点t,求有多少点使得断开其与t直接相连的边后没有从其到t的路径,求出这些点。Solution首先建反向图,此时变成了“单源”问题,记可能为答案的点组成集合S,以当前点与出发点组成的二元组为状态进行bfs,如果当前点与出发点相同就不增加对它的访问次数,也不再对它往外bfs。如果能够到达一个点多次说明这个点不满足要求。上述做法如果中间出现环会有无限次进队,因此考虑剪枝,一个一般的点如果能被两个不同的出发点到达那么此时从第三个及以上的出发点到达该点所组成的状态已经不会对最终答案产生影响,因原创 2021-08-02 16:10:59 · 199 阅读 · 0 评论 -
A - Environment-Friendly Travel(二维最短路)
Question求在路径长度小于等于限制长度前提下起点到终点的最小花费。Solution建图什么的都比较常规,路径长度小于100,求最小花费那就以花费为权跑最短路,剩下的信息当做状态处理好了<node,dist>,注意只保留合法状态(当前距离小于路径长度),跑dijkstra。场上没出是输在对状态的维护上了,dijkstra本质上也是优秀在对同状态对外处理的唯一性上,原来那个写法确实不太能体现这种思想。Code#include <iostream>#includ原创 2021-08-01 16:10:44 · 284 阅读 · 0 评论 -
UVA12118 检查员的难题 Inspector‘s Dilemma
在完全图中找一条欧拉道路,使之经过选中的边且距离最小。等价于将图中各个连通块连接,且使得每个子连通块存在欧拉道路。欧拉道路:存在欧拉道路当且仅当度为奇数的点的个数小于等于2且连通。这里用的并查集维护。#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1005;int .原创 2021-05-16 00:11:15 · 123 阅读 · 0 评论 -
CF700B Connecting Universities
题意:给定一棵树,从其中选择2k个点,求2k个点两两距离和的最大值,边的权值为1。贪心:使每条边产生最大贡献,每条边能产生最大贡献为其两边被选中点的数目的最小值(即这条边最多能被经过多少次),最后答案为每条边所产生的最大贡献的和ans1。正确性:ans1最大:首先不存在任意合法方案的结果大于ans1;ans1合法:每次从贡献最大的路径向两边延伸产生合法路径,可使每条路径的被经过次数为其最大贡献。#include<iostream>#include<cstd..原创 2021-03-29 23:38:11 · 121 阅读 · 0 评论 -
树链剖分(复习+代码解释)
将树上的链通过dfs序映射成一个区间,显然一个子树对应一个连续区间,一条重链对应一个连续区间,一条链可以被分成不超过logn个区间,通过用数据结构(如线段树)维护这些区间可以实现nlogn的维护这些树链树上操作#include <iostream>#include <algorithm>#include <fstream>using namespace std;const int maxn=1e5+10;int n,m,a[maxn],last[..原创 2020-11-28 20:18:39 · 141 阅读 · 0 评论 -
[NOI2018]归程(kruskal重构树)
题意:每天给定一个起点,终点为1,每天可以开汽车过一段海拔高于当天水位线的路,剩下的路步行,问步行最短距离,强制在线。思路:每天的最短距离相当于每天走高于海拔高于水位线的路所能到达的所有点中到1的最短距离。现在要想办法能够直接查询这个最短距离,如果能根据海拔构造一种树状结构,那么每次能开车到达的点对应一颗子树,那么只需要倍增出这颗子树的根节点就可以了。kruskal重构树:对海拔从大到小排序,然后跑kruskal,在求这颗最大生成树的过程中每次两个点不在一个集合,就引入一个新的结点,作为这两个点的代表.原创 2020-11-27 00:06:34 · 288 阅读 · 0 评论 -
UVA515 King
题目描述:n个数,m个限制条件。每一个限制条件形如:1.x y gt c:表示ax + ax+1 + … +ay > c。2.x y It c:表示ax + ax+1 + …… +ax+y < c。有解输出“lamentable kingdom”,否则输出“successful conspiracy”。思路:与intervals那道题很像,题目给出的是和的关系,通过前缀和来得到差的关系,然后就是传统差分约束的建图,求最长路,通过判正环来确定有无解。当时我虽然想到了这道题的核心做法,但是却纠.原创 2020-11-24 16:35:02 · 94 阅读 · 0 评论 -
INTERVAL - Intervals
题目描述:有n个区间,在区间[ai,bi]中至少取任意互不相同的ci个整数。求在满足n个区间的情况下,至少要取多少个正整数。思路:运用前缀和思想,s[i]表示[0,i]最少取多少个数,条件[i,j]取k个数则可以表示成s[j]-s[i-1]>=k,同时考虑i与i-1的限制条件,0<=s[i]-s[i-1]<=1,考虑到0的时候会出现-1,把所有点的编号+1即可,其余按照差分约束建图,求最大值。隐含限制条件:可以证明对隐含限制条件连边在图中有实际意义,0权边使得整个图连通,-1权值边防.原创 2020-11-23 23:25:59 · 211 阅读 · 0 评论 -
差分约束系统(复习)
差分约束系统:给定一组不等式(形如xi-xj<=k),求某两个变量差的最大值或最小值或判断是否有解。给定一系列形如xi-xj<=k的不等式,求差的最大值:连有向边 j->i,权值为k,表示i最多比j大k;建图完成后求最短路即可,若出现负环,则无解。给定一系列形如xi-xj>=k的不等式,求差的最小值:连有向边 j->i,权值为k,表示i最少比j大k;建图完成后求最长路即可,若出现正环,则无解。若出现形如xi=xj的等式,等价于xi-xj<=0、xi-..原创 2020-11-23 21:00:12 · 115 阅读 · 0 评论 -
CF14D Two Paths
给一棵树,保证联通,求两条没有重叠部分的树链长度乘积的最大值。n<=200两条没有重叠部分的树链,一定可以存在于两颗没有重复的子树,进一步转换一下,段掉一条边,把原来的树分成两个子树,求两棵树树的直径乘积,枚举断掉的这一条边即可,求出最大乘积。#include <iostream>#include <cstdio>using namespace std;int n,last[4005],cnt,x,y,maxlen,node,ans,maxn;bool mj[4.原创 2020-11-22 00:37:29 · 103 阅读 · 0 评论 -
UVA1364 Knights of the Round Table
一群骑士,要有若干个(三个及以上的奇数个)骑士围成一个圈开会,有m组冲突关系,对于每一组(i,j),表示骑士i和骑士j不能相邻开会,求有多少个骑士一场会议都不能参加。原创 2020-11-19 23:05:08 · 125 阅读 · 0 评论 -
无向图的点·双联通分量
对于一个连通图G,如果任意两点间至少存在两条“点不重复”路径,则说这个图是点·双联通的。这个要求等价于图的内部无割顶。任意两点都在一个简单环中。对于一张无向图,点·双联通图的极大子图(类似强连通分量)称为双联通分量(BCC)或块(block)。不同双联通分量至多有一个公共点,这个公共点是割顶。计算双联通分量用Tarjan提出的如下算法,用一个栈来维护当前block中的边(其精髓与tarjan算法类似)。int bccno[maxn],iscut[maxn],dfn[maxn],low[maxn],.原创 2020-11-19 12:31:22 · 325 阅读 · 1 评论 -
求无向图中的割顶与桥
对于无向图G(方便起见只考虑联通图),如果删除某个点u后,连通分量数目增加,称u为图的关节点或割顶,对于连通图,割顶就是删除之后使图不再联通的点。对于连通图,删除一条边(u,v)后使图不在联通,则称(u,v)是桥。定理: 在无向图G的dfs树中,非根结点u是G的割顶当且仅当u存在一个子节点v使得v及其后代都没有连回u祖先(u不算)的边。可以类推出, 在无向图G的dfs树中,(u,v)是桥当且仅当v及其v的的后代除了无向边(u,v)以外不存在连回u及其u祖先的边。实现,与tarjan类似,dfn[i].原创 2020-11-18 19:35:30 · 146 阅读 · 0 评论 -
NOI2017 game
对于一般情况下的一组限制u,v:连u->v和!v->!u;若不能选u,则直接跳过这个限制;若不能选v,则连u->!u,表示若是选了u则无解;考虑场地为x的场次不超过8,对于每一场x可以当a,b枚举,这样就是BC或者AC可选,涵盖了ABC所有选择,由于涉及到了枚举,所以采用tarjan+染色的方法;tarjan+染色几次错误原因:1.初始化不全2.染色的点提取错3.多位数的编号当一个字符读4.为了位运算编号从零开始,栈底应初始化为-15.链表存强连通分量点的编号,边界-.原创 2020-11-16 23:51:15 · 84 阅读 · 0 评论 -
Now or later
间隔最小值尽量大,二分时间t。一架飞机的早与晚看成图上两个点i与!i,验证当前mid值,若两点i,j间的间隔<t,则连i->!j,j->!i,表示选了i不能选j,选了j不能选i.注意二分不要写错#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>using namespace std;.原创 2020-11-14 16:21:10 · 170 阅读 · 0 评论 -
2-SAT问题的两种解法+证明(dfs与tarjan)
问题描述:n个布尔变量xi,另有m个需要满足的条件,每个条件的形式都是“xi为真/假或者xj为真/假”。比如:“x1为真或者x3为假”;“或”指的是两个条件至少有一个正确,如上述条件共有三种合法情况:x1真x3真,x1真x3假,x1假x3假。2-SAT问题的目标是给每个变量赋值,使所有条件得到满足。蓝书解法:构造一张有向图G,把其中的每个变量拆成两个结点2i和2i+1,分别表示xi为假和xi为真,最后要为每个变量选择其中的一个结点打标记。对于“xi为假或者xj为假”这样一个条件,我们连一条有向边2i+1.原创 2020-11-12 09:58:16 · 2068 阅读 · 1 评论 -
Tarjan缩点(复习整理)
若两顶点间至少存在一条路径,则称两个顶点强连通。若有向图G中每两个顶点都强连通,则称G为强连通图。非强连通图中的极大强连通子图称为强连通分量。Tarjan算法本质上是一种dfs。dfn[i]:dfs时被遍历的次序(时间戳)。low[i]:最早能回溯到的栈中的点的时间戳。stack[i]:判断i点是否在栈中。dindex:时间戳,stop:栈顶。强连通分量中的点在栈中必定是连续一段。如果一个点x无法回溯到在它之前且在栈中的点,假设它的头顶上还有点,这些点的low值为x或者连接点(连接的连接….原创 2020-11-10 20:26:04 · 424 阅读 · 1 评论