OI-图论
文章平均质量分 65
略
嘉伟森的猫
NYU Shanghai本科,MBZUAI机器学习硕士,深度学习/强化学习菜鸡
展开
-
Luogu 4779(dijkstra+线段树优化)(dijkstra+堆优化)
传送门题意:模板题,求有向非负权图的单源最短路题解:明说了要卡SPFA,所以只能dijkstra+数据结构优化,不管用堆还是线段树,只有能到O(nlogn)就OK。实测线段树略快。注意:每次“出队”时将当前点赋值为INF(如果硬要做删除操作就只有上平衡树了233),线段树在判断“队列为空”的边界时直接判断全局最小值是否等于INF即可。线段树优化dijkstra:#in...原创 2018-08-20 20:57:18 · 731 阅读 · 0 评论 -
Luogu 2024(带权并查集)
传送门 题解1: 在维护并查集同时,维护一个关系域!(好像就是传说中的带权并查集?!) rel[x]表示点x与x所在子树的根的关系,0是同类,1是被吃,2是吃。利用矢量思想,将关系域看成一个x指向root[x]的矢量(太精妙了可惜不是自己想出来的。。。),在合并和判断时可以直接加减。 注意:传参时type-1是为了方便判断(x,y)同类。但是要注意,合并(x,y)时有向的,传参-1的话矢量x原创 2017-08-24 20:29:37 · 368 阅读 · 0 评论 -
hdu 1150(最小点覆盖)
传送门 二分图最大匹配=最小点覆盖 题解:二分图左边点集为机器A的模式,右边为机器B的模式。对于每个任务,左右连边,最后跑一遍二分图最大匹配(最小点覆盖)即可。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=104;int原创 2017-10-12 21:30:50 · 318 阅读 · 0 评论 -
bzoj 4950(二分图最大匹配)
传送门 题意:求在不改变整个区域的三视图的前提下最多能拿走多少的箱子。 题解:(以下均在俯视的情况下) 对于每个有物品的格子,如果它有k个物品,最多能拿走k-1个。 显然只要留下每行每列最大值即可使三视图不变,于是将减多的补回来。然而这么操作有忽略了一个问题,题目说这个家伙可以重新安排物品位置,所以:如果i行,j列最大值相同,那么将只要交点处摆成最大值,其余的取得只剩1。就是说把多的补回来这原创 2017-10-12 21:06:29 · 396 阅读 · 0 评论 -
hihocoder 1181(浅谈佛罗莱算法在求欧拉路径可行解中的应用)
传送门小Ho:这种简单的谜题就交给我吧!小Hi:真的没问题么?小Ho:啊啊啊啊啊!搞不定啊!!!骨牌数量一多就乱了。小Hi:哎,我就知道你会遇到问题。小Ho:小Hi快来帮帮我!小Hi:好了,好了。让我们一起来解决这个问题。小Hi:原来是这样。。。小Ho你仔细观察这个例子:因为相连的两个数字总是相同的,不妨我们只写一次,那么这个例子可以写成:3-2-4原创 2017-10-12 18:50:09 · 423 阅读 · 0 评论 -
lightoj 1123(增量最小生成树)
传送门每次跑最小生成树,如果生成环就把当前边(无效边)去掉。#include#include#include#includeusing namespace std;const int MAXN=204,MAXM=6004;int n,m;int fa[MAXN];struct EDGE { int u,v,w; bool operator <(const EDGE原创 2017-10-12 19:34:29 · 373 阅读 · 0 评论 -
Luogu 3386(二分图最大匹配)
传送门模板题。新技能get:存增广标记的cov数组如果使用int类型就不用每次memset(以前的版本在之前的博文中有过),可以大幅节约时间。晚安~#include#include#include#include#includeusing namespace std;const int N=1004;int n,m,eg;int head[N<<1],etot=0;原创 2017-11-06 22:25:59 · 288 阅读 · 0 评论 -
Luogu 3388(割点)
传送门注意:统计割点个数一定要注意算重!!!有多个儿子使当前点成为割点时计数器也只能加一次!!!#include#include#include#includeusing namespace std;const int N=1e5+4;int n,m,dfn[N],low[N],tim=0,cut=0;int head[N],etot=0;struct EDGE { in原创 2017-11-06 19:40:37 · 304 阅读 · 0 评论 -
Luogu 3379(LCA)
传送门模板题,我用倍增居然把它卡过了。(拒绝vector支持链式前向星!)P.S.在欧拉序列上进行RMQ也可以做到O(1)。倍增:#include#include#include#includeusing namespace std;const int N=5e5+4;int n,q,rot;int dep[N]={0},f[20][N];int head[N],e原创 2017-11-06 17:14:07 · 275 阅读 · 0 评论 -
bzoj 1123(tarjan)
传送门 题意:在一个无向连通图中,求出对于每一个点,割掉该点有多少对有序点对不连通。(删掉的点也算)题解: 由tarjan求割点时顺便维护dfs树上的siz和ans。P.S.注意枚举来自不同儿子的子树点对时的写法,这样操作算的是无序点对(后面的不会再与之前的匹配),所以最后答案要乘以2。#include<cstdio>#include<cstring>#include<iostream>#原创 2017-10-11 21:04:27 · 283 阅读 · 0 评论 -
poj 3352(tarjan)
传送门 题意:加最少的边使原图(保证所有点连通)成为一个边-双连通图。 题解:用tarjan求双连通分量缩点(形成一棵无根树)后计算度数为1的节点(叶节点)的个数为cnt,那么答案为(cnt+1)/2。下面是证明:首先把两个最近公共祖先最远的两个叶节点之间连接一条边,这样可以把这两个点到祖先的路径上所有点收缩到一起,因为一个形成的环一定是双连通的。然后再找两个最近公共祖先最远的两个叶节点,这样一原创 2017-10-11 09:14:08 · 302 阅读 · 0 评论 -
Luogu 1525(并查集)(NOIP 2010)
传送门NOIP 2010 T3题解:1.二分图匹配2.镜像并查集P.S.小心答案为0#include#include#include#includeusing namespace std;const int MAXN=2e4+4,MAXM=1e5+4;int n,m;int fa[MAXN<<1];struct EDGE { int u,v,w; f原创 2017-10-20 19:20:28 · 268 阅读 · 0 评论 -
Luogu 1186(SPFA)
传送门 题解: 因为只有最短路上的边被断才对新最短路有影响,所以: 1.先跑一遍最短路 2.枚举最短路上每一条边,将其断掉,再跑最短路 3.输出所有最短路的最大值P.S.之前WA了好几次是因为把原来的最短路径树当成原来的最短路了。。。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#incl原创 2017-10-11 16:51:04 · 191 阅读 · 0 评论 -
poj 1637 (浅谈最大流在解决混合图欧拉回路中的应用)
传送门 题解: 本人的欧拉路径专题总结☜戳这里。在#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int MAXN=202,MAXM=1002,INF=0x3f3f3f3f;int n,m;int head[原创 2017-10-11 20:00:13 · 442 阅读 · 0 评论 -
bzoj 4668(并查集按秩合并)
传送门题意:两种操作,强制在线。1.将u,v连边2.询问u,v最早什么时候已经连通题解:每次连边就更新时间戳赋成每个点的点权,查询链上最大值,所以不能压缩路径(压了路径无法解决分叉的情况),为了保证复杂度,采用按秩合并(复杂度mlogm?)。#include#include#include#includeusing namespace std;co原创 2017-10-13 08:36:03 · 361 阅读 · 0 评论 -
hdu 3047(带权并查集)
传送门昨天才考过一道差不多的,用离线+BFS预处理+裸并查集水掉了(^_^)题意:有n个人坐在zjnu体育馆里面,然后给出m个他们之间的距离, 代表B的座位比A多X.。然后求出这m个关系之间有多少个与之前的关系有冲突。题解:用带权并查集维护点到根距离,在merge操作时:P.S.注意每组数据初始化时dis也要清空!!!#include#include#i原创 2017-10-13 09:08:47 · 276 阅读 · 0 评论 -
Luogu 1967(货车运输)(最大生成森林+LCA)
传送门题意:有 nn 座城市,编号从 11 到 nn ,城市之间有 mm 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。题解:由于要装尽量多的货物,所以先用kruskal跑一个最大生成森林,然后再因为存在短板效应,所以在这些生成的树上跑倍增(可参考倍增求LCA),求出每条询问的路径上的最...原创 2018-08-19 18:41:55 · 309 阅读 · 0 评论 -
bzoj 2208(tarjan+拓扑排序+bitset)
传送门题意:求一个有向图中可达顶点对数(每个点可达其自身)题解:听说可以直接用floyd传递闭包+bitset,但是为了提高效率顺便复习算法,还是采用tarjan先缩点然后反向建图在DAG上一边拓扑排序一边用bitset传递可达点集。去年的bitset今年终于会用了......#include<cstdio>#include<cstring>#incl...原创 2018-08-16 14:39:55 · 225 阅读 · 0 评论 -
bzoj 1787(LCA)
传送门题意:一棵树 N 个结点的树,有 M 次查询:树上三个点到哪个点的距离之和最小。题解:求(a,b)(b,c)(c,a)三对点的LCA,深度最深的那个即使答案:下面口胡一下证明过程:三个LCA如果发生重合,那么显然上述做法正确,不再赘述。如果三个LCA互不相同,那么它们一定可以组成一个二叉结构,从将最浅的LCA作为答案,将其往另外两个移动,每移动一次距离之和+1-2。显原创 2017-10-26 15:51:03 · 244 阅读 · 0 评论 -
bzoj 1598(SPFA+A*)
传送门~~~A*的经典应用~~~题解:先预处理反向图的单源(T)最短路,之后启发式搜索,每次从优先队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数,如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束,否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先队列继续搜。#include#include#include#原创 2017-10-22 12:53:08 · 264 阅读 · 0 评论 -
bzoj 1977 (浅谈如何hack掉hzwer学长)(严格次小生成树)(LCA+kruskal)
传送门题解:(**以下内容出自代码有错但是过了bzoj评测的hwzer学长**)先求出最小生成树,要严格次小。枚举每一条非树边找俩顶点树链上的最大边(如果最大边相同与非树边边权相同则找次大边)然后更新最小增量。最大边和次大边可以通过树上倍增求出。下证hzwer学长和其他一些同学的错误,以hzwer的代码为例:void cal(int x,int f,int v){ int原创 2017-10-15 21:50:29 · 758 阅读 · 2 评论 -
Luogu 3371(dijkstra堆优化)
传送门模板题。此版本无遍历标记,只能过弱化版数据......#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int N=10004,M...原创 2017-11-09 21:27:31 · 344 阅读 · 0 评论 -
hihocoder 1098(kruskal)
传送门模板题,原计划觉得kruskal稳如狗根本不用管,但是保险起见还是敲一遍,如果忘了就吃键盘。#include#include#include#includeusing namespace std;const int N=1e5+4,M=1e6+4;int n,m,fa[N];struct EDGE { int u,v,w; friend bool operator原创 2017-11-09 19:57:18 · 309 阅读 · 0 评论 -
UOJ 261/bzoj 4719(LCA)(NOIP2016)(天天爱跑步)
传送门 对于在st->en路径上的一点x,显然有两种情况: Case1: x在st->LCA上 Case2: x在LCA->en上 对于Case1,显然满足关系式dep[st]-dep[x]=w[x],那么dep[st]=dep[x]+w[x],那么我们只需要找出以x为根的子树中,dep满足条件的即可。 对于Case2要稍微麻烦一些。写出关系式:dep[x]+dep[st]-2*dep[原创 2017-09-29 17:35:29 · 243 阅读 · 0 评论 -
bzoj 4443(二分+二分图最大匹配)
传送门题解:二分答案x,对于权值不大于x的点行列连边,跑二分图最大匹配,如果匹配数小于n-k+1(第k大即第n-k+1小),则left增大,否则right减小。最后分到的left+1一定是答案。#include#include#include#includeusing namespace std;const int MAXN=254,INF=0x3f3f3f3f;int原创 2017-10-13 20:32:42 · 254 阅读 · 0 评论 -
bzoj 1202(差分约束)/(带权并查集)
传送门 如果看到题不知道要转前缀和就可以退竞晒了。。。 题解1: (差分约束我居然1A了啦啦啦~~~,虽然这是道大水题) s[b]-s[a-1]=c,一看就是差分约束的套路: s[a-1]≤s[b]-c,连边(b,a-1,-c) s[b]≤s[a-1]+c,连边(a-1,b,c) 将所有点push进队列用SPFA找负权环即可,找到为false,没有为true。#include<cstd原创 2017-10-13 14:39:55 · 429 阅读 · 0 评论 -
hdu 1829(带权并查集)
传送门 题解:并查集维护0/1权值。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=2004;int n,m;int fa[MAXN];bool val[MAXN];inline int read() { int原创 2017-10-13 11:13:43 · 257 阅读 · 0 评论 -
Luogu 3387(tarjan+dp)(tarjan+SPFA)
传送门 直接tarjan缩点,然后在DAG上dp一下最长路即可。#pragma comment(linker,"/STACK:1024000000,1024000000")#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define root 1,n,1#define lson l,mid,r原创 2017-08-29 23:00:52 · 341 阅读 · 0 评论 -
Luogu 1074(tarjan+dp)
传送门 NOIP 2009 T3 题解:可以用两边SPFA过,也可以用tarjan+dp过。 如果使用第二种方法,那么记录一下每个强连通分量内的最大最小值,然后设f[i]为从1所在强连通分量到i所在强连通分量,用类似SPFA的BFS更新f值,最后输出f[n]。P.S.两边SPFA的做法:从1用正向边搜一遍最小值(最短路),从n用反向边搜一遍最大值(最长路),然后用两遍都经过的点的最大最小值之差原创 2017-10-11 15:11:22 · 227 阅读 · 0 评论 -
UVa 10099(kruskal/Floyd)
传送门 题解: 求每条路径上最小权值的最大值,数据范围是出给Floyd,但是可以用kruskal构造最大生成树实现。 P.S.本人做UVA说是要巩固基础,另一大原因就是想刷点访问量╮(╯▽╰)╭,一道大水题做了接近半个小时,真是点背。。。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#incl原创 2017-10-10 20:58:16 · 387 阅读 · 0 评论 -
树边,前向边,后向边,横叉边
图片来自:http://blog.csdn.net/u014665013/article/details/51351371在图的遍历中,往往设置了一个标记数组vis的bool值来记录顶点是否被访问过。但有些时候需要改变vis值的意义。令vis具有3种值并表示3种不同含义 vis = 0,表示该顶点没没有被访问 vis = 1,表示该顶点已经被访问,但其子孙后代还没被访问完,也就没从该点返回 v原创 2017-08-31 15:48:17 · 410 阅读 · 0 评论 -
bzoj 3732(kruskal+LCA)
传送门 题解:先求出MST,然后在跑倍增LCA时顺便维护一个dp数组记录路径上的最大边权。 P.S.WA了好久,因为LCA跳最后一步没取max。。。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=15004;int n,m,原创 2017-09-16 22:07:59 · 209 阅读 · 0 评论 -
bzoj 4390(LCA+差分)
传送门 题解: 树上差分:对于修改操作的每一对(x,y),x,y的sum都加1,lca(x,y)和fa[lca(x,y]的sum都-1。虽然确实是一道水题,但是这种树上差分以前还真的只是听过,没有亲手尝试,要是现在不写写,万一考试写挂了怎办orz。。。其它解法: 1.DFS序+线段树/树状数组,最后暴力查询每个点(或者更优的,本蒟蒻没想到的统计答案方式) 2.树链剖分,复杂度多一个log(n原创 2017-09-16 20:23:23 · 314 阅读 · 0 评论 -
bzoj 3910(LCA+并查集)
传送门 题解:两点间路径唯一就是树啊。。。我这都没看出来,可以退竞晒了。。。LCA不用说,每次询问当前起点(起点不断更新)到当前目标点的距离,这个询问操作就涉及到LCA。然后用维护经过的路径,走过的就把一条链都merge到一起,这个正好就用并查集啊!又是一道”一看题解就懂系列“的题。。。╮(╯▽╰)╭ P.S.自己写的LCA就是快╰(°▽°)╯#include<cstdio>#include<原创 2017-09-16 19:51:40 · 525 阅读 · 0 评论 -
Luogu 1144(SPFA+dp)
传送门 题解:先跑一遍SPFA,然后再dp,如果dis[v]+1==dis[p],则有ans[p]=(ans[p]+ans[v])%MOD 注意:ans[1]初始化为1(1的最短路就是0,有一条),否则ans跑出来全是0……#include<bits/stdc++.h>using namespace std;const int MAXN=1e6+2,MAXM=2e6+2,MOD=1e5+3;原创 2017-08-30 22:58:58 · 275 阅读 · 0 评论 -
codevs 2822(tarjan)
传送门 题解: 第一问:输出size大于1的强连通分量的个数(注意测试点1的特判,此测试点没有size大于1的连通分量。。。) 第二问:统计出度为0的分量个数,由于整个图连通,所以出度为0的分量一定能被其余所有分量走到,当且仅当这样的分量只有一个,大于一个则输出-1(可以理解为出现了“分叉”的情况)。#include<cstdio>#include<cstring>#include<ios原创 2017-09-15 20:16:58 · 247 阅读 · 0 评论 -
poj 3207(2-SAT)
传送门 题解:本人第一道2-SAT,但是好像还不包括2-SAT所有操作,只判了可行性。对于每一对点有两个选择:从圆内连和从圆外连。限制:连线不能相交,相交的只选一个即可(判断位置关系自己yy吧很简单的)。#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<stack>using na原创 2017-09-15 12:16:24 · 224 阅读 · 0 评论 -
Luogu 2661(tarjan)
传送门 可以用预处理后dfs搜索最小环来做,反正本蒟蒻用tarjan求最小强连通分量水过了,一开始感觉这样并不太严谨,因为最小的SCC不一定是最小环吧(最小环是最小的SCC的子集)。。。但是–几分钟后发现,对于所有点出度只有1的图来说,最小环好像一定是一个SCC,一定可以用tarjan搜出来! 不过,这个办法对于一般的有向图慎用!!!#include<bits/stdc++.h>using n原创 2017-08-23 22:37:04 · 241 阅读 · 0 评论 -
bzoj 2330(差分约束)
传送门 题意:略 差分约束后SPFA求最长路,注意判环和输入时特殊不合法情况(某人拿的糖果不能多于自己)P.S.竞赛生两周的暑假结束前最后做点题压压惊╮(╯▽╰)╭ #include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=1e5+2;int n,m;int dis[maxn],in[m原创 2017-08-15 21:35:35 · 278 阅读 · 0 评论 -
hdu 2767(tarjan)
传送门 问题:最少加几条有向边使原图形成一个强连通图? tarjan缩点后形成一个DAG(有向无环图),统计入度为0的点个数和出度为0的点个数,最后答案为两者的最大值maxx,如果整个DAG为一个点,则答案为0(Special Judge),本蒟蒻只会感性证明,理性证明如果有哪位大佬会的话希望能在评论区指点一下。 感性证明: 在DAG中从出度为0的点加边连向入度为0的点,连maxx的边一定可原创 2017-08-01 23:11:43 · 226 阅读 · 0 评论