随笔分类 - 算法竞赛 / 算法竞赛 - 图论
摘要:定义 欧拉回路Eulerian Cycle:通过图中每条边恰好一次的回路 欧拉通路Eulerian Path:通过图中每条边恰好一次的通路 欧拉图:具有欧拉回路的图 半欧拉图:具有欧拉通路但不具有欧拉回路的图 欧拉图中所有顶点的度数都是偶数。 若 G 是欧拉图,则它为若干个环的并,且每条边被包含在奇
阅读全文
摘要:树的重心的定义是,对树中的某个点,以这个点为根,然后它会拥有若干棵子树,取出最大的那棵子树的size,然后在所有点中求最小的最大的子树的size的点,这个点就是树的重心。简单来说就是找到某个点r,去掉r之后,每棵子树是长得最平均的。树的重心最多有2个(这时候重心其实是在这两点之间的边上),最少有1个
阅读全文
摘要:原本不想写这个的,但是今天错了一次。写一下让自己以后多一个参考。 Floyd算法初始化两点之间的距离为无穷大,然后自己到自己的距离为0。 然后枚举所有的边,初始化对应两点的边权,注意处理平行边或者自环的情况。推荐用min操作。 第一维枚举中转点k,也就是阶段。 第二第三维枚举图中的两点i, j,也就
阅读全文
摘要:匈牙利算法,优点:代码短 邻接矩阵:复杂度 \(O(n^3)\) 。邻接表:复杂度 \(O(nm)\) 。 /* nx X侧顶点的数量 ny Y侧顶点的数量 vis 顶点i是否在交错路中 cx X侧顶点i匹配的Y侧顶点 cy Y侧顶点i匹配的X侧顶点 */ const int MAXN = 500
阅读全文
摘要:https://codeforces.com/contest/1281/problem/F 题意:每个顶点有两个权值b和w。最多3000个节点的树,分成恰好m个非空的连通块,使得尽可能多的连通块满足w的和严格大于b的和。 树上背包的套路题,这里背包 \(dp[i][j]\) 表示以i为根的子树,已经
阅读全文
摘要:https://github.com/lydrainbowcat/tedukuri/blob/master/%E9%85%8D%E5%A5%97%E5%85%89%E7%9B%98/%E6%AD%A3%E6%96%87%E5%8C%85%E5%90%AB%E7%9A%84%E7%A8%8B%E5%B
阅读全文
摘要:2-SAT,表示为一系列约束 \(x_i\; or\; x_j\) 即两个变量中至少选择一个为真。 那么,假如其中一个选择了假,另一个一定要选择为真。 拆点,把变量 \(x_i\) 取真用点 \(V_i\) 表示,变量 \(x_i\) 取假用点 \(V_{i+n}\) 表示。那么上面的一个约束就连边
阅读全文
摘要:一般图,通过点双连通分量建立圆方树,每个点双连通分量建一个方点,方点向原图的点(圆点)连边,圆点之间的边(原图的边)删去。变成一棵树。
阅读全文
摘要:不存在桥的图,称为边双连通图。原图可以经过tarjan算法求出桥,桥就连接了两个边双连通分量,假如把桥的都堵住(注意是只能把桥堵住,不能堵住点),然后每一块找一次连通块,就可以找到每个点所属的双连通分量,然后可以缩点成一棵树。 struct EBCC { static const int MAXN
阅读全文
摘要:A*算法: 单源单汇第k短路: 给定一个源点s和一个汇点t,求解从s到t的第k短路。 建立反图,从反图中,以t为源点跑单源最短路,得到原图中i点到t点的最短路val[i](也就是反图中t点到i点的最短路) 用val[i]作为估价函数,当前**状态(dis[i],i)**的距离为dis[i],把(di
阅读全文
摘要:给定一组不等式: \(x_{v1}-x_{u1}\le w_1\) \(x_{v2}-x_{u2}\le w_2\) (注意上面的变量的位置是(v,u,w)而不是(u,v,w)) 求满足上面约束的一组可行解,变形为 \(dis[v_1]\le dis[u_1]+w_1\) ,故从点 u 连接一条权值
阅读全文
摘要:常见技巧: 新建超级源点:例如求到达一个点集中的任意一个点的最短路,就把这个点集的点都从一个超级源点连出 分层图最短路:给最短路多带上一个属性(例如使用某个优惠条件/加倍条件k次,有时候可以提前使用或者存储起来以后使用某个条件) 同余最短路:给n个整数a1,a2,an,求他们不能线性组合出的[lim
阅读全文
摘要:适用于求解没有负环的全源最短路,最坏时间复杂度 \(O(nm\log m)\) 比Floyd要优秀(但是Floyd可以找出负环)。 在没有负权边时,使用n次单源最短路Dijkstra代替即可。 算法流程: 1、新建一个虚拟节点(编号为n+1),向[1,n]连接一条边权为0的虚拟边。 2、从n+1号节
阅读全文
摘要:适用于任何权的图,负权也可以做。假如从s出发的子图中存在负环,则算法会报告发现负环,否则会正确求出最短路。 松弛操作 一种基于松弛(relax)操作的最短路算法。 第i轮松弛(每条边使用一次)后,从节点s出发的经过<=i条边的到达每个节点的最短路已经找到。假如存在最短路,则最多经过n-1条边。所以假
阅读全文
摘要:其实格子图很可能会和棋盘格染色有关。 namespace BFS { const int MAXN = 1e3 + 10; const int MAXM = 1e3 + 10; const int di[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dj[]
阅读全文
摘要:当边权为某个定值w时,可以直接把最短路改为经过w边几次,那么可以用bfs。 namespace BFS { const int MAXN = 3e5 + 10; int n; vector<int> G[MAXN]; int dis[MAXN]; queue<int> Q; void bfs(int
阅读全文
摘要:最大匹配数=最小点覆盖数(选最少的点,使得每条边至少选中一个点) 每个匹配任意选一个点。选出的点集恰好每条边至少覆盖一个端点,否则,存在一条边两端都没有被覆盖,那么这条边应该存在于最大匹配中。所以选出的点集足够覆盖整个图。(怎么证明是最小的呢) 最大独立集(最大的点集S使得点集中任意两个点均不联通)
阅读全文
摘要:流量均为1。拆点S,限流为1,对于一个权值w的区间[L,R],从源点连到L,从R连到T,从L连到R容量为1,费用为w,每个点i向i+1连边。跑最大费用最大流,就会选出一串区间。
阅读全文
摘要:例如从给某个区间A=[La,Ra]中的所有节点给区间B=[Lb,Rb]的所有节点都分别连接一条权值为w的边,求最短路。 对整个图建两棵线段树A和B。线段树A的内部,小区间走到大区间没有成本,连接0权值的边(象征着放弃小区间的特异性,在包含这个小区间的更大的集合中寻找机会)。线段树B的内部,大区间走到
阅读全文
摘要:const int MAXN = 2e5 + 10; vector<int> G[MAXN]; int dis[MAXN], mxdis; void dfs(int u, int p) { dis[u] = dis[p] + 1; if(dis[u] > dis[mxdis]) mxdis = u;
阅读全文