模板:强连通分量&2-sat】的更多相关文章

Kosaraju算法 O(n+m) vector<int> s; void dfs1(int u) { vis[u] = true; for (int v : g[u]) if (!vis[v]) dfs1(v); s.push_back(u); } void dfs2(int u) { color[u] = sccCnt; for (int v : g2[u]) if (!color[v]) dfs2(v); } void Kosaraju() { s.clear(); for (int i…
int dfn[N], low[N], dfncnt, s[N], tp; int scc[N], sc; // 结点 i 所在 scc 的编号 int sz[N]; // 强连通 i 的大小 void tarjan(int u) { low[u] = dfn[u] = ++dfncnt, s[++tp] = u; for(int i = h[u]; i; i = e[i].nex) { const int &v = e[i].t; if(!dfn[v]) tarjan(v), low[u] =…
关于如何求强连通分量的知识请戳 https://www.byvoid.com/blog/scc-tarjan/ void DFS(int x) { dfn[x]=lowlink[x]=++dfn_clock; stac.push_back(x); ; i<g[x].size(); i++) //与x相连的个点 { int t=g[x][i]; if(!dfn[x]) //未访问过 { DFS(t); lowlink[x]=min(lowlink[x],lowlink[t]); } else if…
贴模板,备忘. 模板1: #include<iostream> #include<cstring> #include<cmath> #include<cstdlib> #include<cstdio> #include<algorithm> #include<string.h> using namespace std; struct node { int v,next; }edge[]; ],LOW[]; ],heads[…
PS:摘自一不知名的来自大神. 1.割点:若删掉某点后.原连通图分裂为多个子图.则称该点为割点. 2.割点集合:在一个无向连通图中,假设有一个顶点集合,删除这个顶点集合,以及这个集合中全部顶点相关联的边以后.原图变成多个连通块.就称这个点集为割点集合. 3.点连通度:最小割点集合中的顶点数. 4.割边(桥):删掉它之后,图必定会分裂为两个或两个以上的子图. 5.割边集合:假设有一个边集合.删除这个边集合以后,原图变成多个连通块.就称这个点集为割边集合. 6.边连通度:一个图的边连通度的定义为,最…
看了好久才终于明白了这个算法..复杂度是O(n+m). 我觉得这个算法不是很好理解,但是看懂了以后还是觉得听巧妙的. 下面给出模板代码和三组简单数据帮助理解. 代码如下: #include <stdio.h> #include <stack> #include <algorithm> #include <string.h> #include <vector> using namespace std; +; stack<int> S;…
Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using namespace std; ; + ; struct EDGE{ int v, nxt; }Edge[maxm]; int Head[maxn], cnt; int DFN[maxn], LOW[maxn], color[maxn], INDEX, id; bool vis[maxn]; int N, M;…
Tarjan求强连通分量的流程在这个博客讲的很清楚,再加上我也没理解透,这里就不写了. 缩点:将同一个连通块内的点视为同一个点. 扔一道模板题:codeVS2822爱在心中 第一问很显然就是求点数大于一的连通块的个数,跑一次tarjan: 第二问脑补一下发现,缩点后,若图中有且仅有一个点出度为0且为爱心天使,则该点为所求的特殊爱心天使: 因为当缩点之后,图中不存在环,若有且仅有一个爱心天使出度为0,那么其他点一定有通向该爱心天使的路径. 若有两个点出度为0,那么他们彼此不被对方所爱. 若没有点出…
#include<iostream> #include<stdio.h> #include<string.h> #include<stack> #include<vector> #include<algorithm> #define N 1000 using namespace std; int pre[N],lowlink[N],sccno[N],dfn_clock,scc_cnt; stack<int> stk; ve…
功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量 原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点 这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有向图可以有效的进行缩点(每个强连通分量缩成一个点),构成一个新的拓扑图(如BZOJ上Apio2009的那个ATM)(PS:注意考虑有些图中不能通过任意一个单独的点到达全部节点,所以不要以为直接tarjan(1)就了事了,还要来个for循环,不过实际上复杂度还是O(M),因为遍历过程中事实上每个边还是…