专题链接
关于tarjan
A - Network of Schools 原题地址
本题有2个问题,第一个是要算最少要给多少个点软件,才能使所有点都可以收到副本
第二个是要算最少加多少条边,使得图变成强连通
1:tarjan求强连通,然后缩点,计算入度为0的强连通分量
2:设现在有a个入度为0的点,b个出度为0的点(缩完点后的点),最合理的加边方法肯定是从出度为0的点向入度为0的点添加有向边,
如果a > b, 添加a条边,所有点的入度都大于0,所有点的出度也大于0,问题解决,答案是a
如果 a <= b,添加a条边,所有点入度大于0,但是还有b-a个点,它们的出度是0,所以还要再加b-a条边,所以答案是b
综合两种情况,答案是max(a,b)
当然如果图原来就是强连通的话,输出就是1 和 0 了
#include
B - Network 原题地址
求割点数目,模版题
#include
C - Critical Links
求桥,模版题,这题似乎不用判重边
#include
D - Network 原题地址
敢不敢不叫 Network了
询问每次添加一条边以后剩下的桥的数目
先一次tarjan缩点,得到一颗树,每次 加边,两个端点到它们的lca之间的边都不再是桥,所以每一次我们都可以通过暴力求出lca,然后统计出少了多少条桥,但是暴力统计时,会遇到某些边在之前就不是桥的情况,我们用并查集来跳过这些边(每一次加边就把lca路径上的点都合并到一个集合里去,这里根用最上面的点,到时如果遇到这种点,直接可以跳到它们的根上去)
#include
E - Redundant Paths 原题地址
求桥的数目,模版题,注意重边的判定
#include
F - Warm up 原题地址
询问如何加一条边,使得剩下的桥的数目最少,输出数目
我的做法是先tarjan缩点,得到树,然后求出树的直径,把边加在直径的两端,减少的桥肯定是最多的
#include
G - Strongly connected 原题地址
求最多可以加多少边,使得最新的图不是强连通图
最终情况一定是再加一条边,整张图就是强连通的了,那么我们可以把图看成2部分x和y,x和y都是完全图,然后x每个点到y每个点都有边,但是y到x没有边,如果有肯定是强连通了,设x中有a个点,y中有b个点 则 a + b = n
则边数就是 a * (a - 1) + b * (b - 1) + a * b - m,化简得到:n * n - a * b - n - m;
如何让这个值大那就是如何选取x和y的问题了,显然a和b差距越大越好,那么就可以通过tarajan来找出一个包含点最少的强连通分量来当x,其他的强连通分量作为y,这样就很容易了
#include
H - Prince and Princess 原题地址
首先做一次最大匹配,设为cnt,那么对于左边,有n-cnt个王子没有匹配,对于右边,有m-cnt个公主没有匹配,所以我们在左边加上m-cnt个虚拟点,这些点喜欢所有公主,右边加上n-cnt个虚拟点,这些点被所有王子喜欢,这样左右两边都是n+m-cnt个点,在求一次最大匹配,这一定是一个完备匹配,对于每一个王子,用他目前匹配的公主,向所有他喜欢的公主连一条有向边,这表示单方面可以替换,所以再对得到的新图求强连通,处在一个强连通分量的公主可以相互替换
#include
I - Caocao's Bridges 原题地址
此题其实不难,但是很坑
1:如果图不连通,那么不需要派人去
2:如果有一条桥,防卫兵数目为0,那么应该派1个人去
3:重边判定
#include