#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5, M = 1e5; struct Edge { int v, next, idx; Edge(){} Edge(int _v, int _next, int _idx): v(_v), next(_next), idx(_idx){} }e[M]; int dfn[N], dee…
一.基本概念 1.桥:若无向连通图的边割集中只有一条边,则称这条边为割边或者桥 (离散书上给出的定义.. 通俗的来说就是无向连通图中的某条边,删除后得到的新图联通分支至少为2(即不连通: 2.割点:若无向连通图的点割集中只有一个点,则称这个点为割点或者关节点 : 通俗的来说就是无向连通图中的某条边,删除后得到的新图连通分支至少为2: 二:tarjan算法求割点和桥 1.割点:1)当前节点为树根的时候,条件是“要有多余一棵子树”:     如果这有一颗子树,去掉这个点也没有影响,如果有两颗子树,去…
#include <cstdio> #include <cstring> #include <iostream> #include <vector> using namespace std; ; vector<int>tu[maxn]; vector<int>lt[maxn]; ; ; int dfn[maxn],low[maxn]; ; bool isins[maxn]; void tarjan(int i) { int j; df…
大约是今年4月学的算法了,后来5月的时候做题还写了一个退化的tarjanQAQ. 时间复杂度:O(n+m) 用途:有向图缩环 #include<set> #include<cmath> #include<ctime> #include<queue> #include<stack> #include<cstdio> #include<vector> #include<cstring> #include<cs…
功能:输入一个N个点,M条单向边的有向图,求出此图全部的强连通分量 原理:tarjan算法(百度百科传送门),大致思想是时间戳与最近可追溯点 这个玩意不仅仅是求强连通分量那么简单,而且对于一个有环的有向图可以有效的进行缩点(每个强连通分量缩成一个点),构成一个新的拓扑图(如BZOJ上Apio2009的那个ATM)(PS:注意考虑有些图中不能通过任意一个单独的点到达全部节点,所以不要以为直接tarjan(1)就了事了,还要来个for循环,不过实际上复杂度还是O(M),因为遍历过程中事实上每个边还是…
//to update 边的分类 有向图边分为四类: 树边, 前向边, 返祖边(后向边), 横叉边. 上图: 判定 有向图 对图进行dfs, 不考虑已经遍历过的点, 得到dfs序 \(dfn_i\). 在dfs过程中, 记录当前dfs栈. 对于边\((u,v)\), 树边: \(vis_v==0\); 前向边: \(vis_v==1\) 且 \(dfn_v > dfn_u\); 返祖边: \(vis_v==1\) 且 \(dfn_v < dfn_u\), 且 \(v\) 在当前栈内; 横叉边:…
题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先tarjan缩点,再从入度为零处进行一次拓扑排序,求最长路即可,话说拓扑排序求最长路真方便... 注意: 要明确拓扑的写法,用栈写最优. 再进行拓扑排序之前我们要进行将点权转化为边权的操作,具体操作看拓扑排序. #include<bits/stdc++.h> using namespace std;…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意: 给出一棵 n 个节点的带边权的树, 有 m 个形如 x y 的询问, 要求输出所有 x, y节点之间的最短距离. 思路: dis[i] 存储 i 节点到根节点的最短距离, lca 为 x, y 的最近公共祖先, 那么 x, y 之间的最短距离为: dis[x] + dis[y] - 2 * dis[lca] . 解法1: tarjan离线算法 关于该算法 Tarjan(u)//marg…
int dfn[MAXN],low[MAXN],cnt; void tarjan(int x,int edg) { low[x]=dfn[x]=++cnt; for(int i=f(x);i;i=n(i)) if(!dfn[v(i)]) { tarjan(v(i),i); low[x]=min(low[x],low[v(i)]); if(low[v(i)]>dfn[x]) isbridge[i]=isbridge[i^]=; } )) low[x]=min(low[x],dfn(v(i)));…
int dfn[MAXN],low[MAXN],cnt,root; bool iscut[MAXN]; void tarjan(int x) { dfn[x]=low[x]=++cnt; ; for(int i=f(x);i;i=n(i)) if(!dfn[v(i)]) { tarjan(v(i)),low[x]=min(low[x],low[v(i)]); if(low[v(i)]>=dfn[x]) { flag++; )iscut[x]=; } } else low[x]=min(low[x…