-
每次向下搜点,\(dfn[i]\)表示搜到第\(i\)点时的编号,\(low[i]\)表示第\(i\)个点能到达的最小的点的编号,我们在搜的时候可以把路径上的点存入到栈中,当\(dfn[i]=low[i]\)时,说明我们已经找完一个强连通子图了,此时就可以把栈中的元素出栈得到一个强连通子图.
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int n,m; vector<int> edge[N]; int dfn[N],low[N],timestamp; int stk[N],top; bool in_stk[N]; int id[N],scc_cnt; void tarjan(int u){ dfn[u]=low[u]=++timestamp; stk[++top]=u,in_stk[u]=true; for(auto w:edge[u]){ if(!dfn[w]){ tarjan(w); low[u]=min(low[u],low[w]); } else if(in_stk[w]) low[u]=min(low[u],dfn[w]); } if(dfn[u]==low[u]){ ++scc_cnt; int y; do{ y=stk[top--]; in_stk[y]=false; id[y]=scc_cnt; }while(y!=u); } } int main(){ ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n>>m; rep(i,1,m){ int u,v; cin>>u>>v; edge[u].pb(v); } rep(i,1,n){ if(!dfn[i]) tarjan(i); } return 0; }
相关文章
- 10-26你需要知道的九大排序算法【Python实现】之堆排序
- 10-26基于WAF入侵检测和变异WebShell检测算法的Web安全研究
- 10-26ETL拉链算法大全(搬运)
- 10-26ZAB协议与Paxos算法
- 10-26ZAB协议工作机制与及他与PAXOS算法的区别
- 10-26Paxos算法
- 10-26AcWing算法提高课【第三章图论】第一部分
- 10-26多目标遗传算法 ------ NSGA-II (部分源码解析) 实数、二进制编码的变异操作 mutation.c
- 10-26算法题:int 数组中 只有一个是id 只出现一次 其他都出现2次 怎么找出只出现一次的id
- 10-26【20160924】GOCVHelper MFC增强算法(2)