tarjan 模板html
#include <iostream> #include <string.h> using namespace std; const int MAX_N = 100; const int MAX_M = 10000; struct edge{ int v,next; int len; }E[MAX_M]; int p[MAX_N],eid; int dfn[MAX_N],low[MAX_N]; int idx = 0; int belong[MAX_N],scc = 0; int s[MAX_N],top = 0; bool in_stack[MAX_N]; void init(){ memset(p,-1,sizeof(p)); eid = 0; } void insert(int u,int v){ E[eid].v = v; E[eid].next = p[u]; p[u] = eid++; } void tarjan(int u){ dfn[u] = low[u] = ++idx; s[top++] = u; in_stack[u] = true; for(int i=p[u];i+1;i=E[i].next){ int v = E[i].v; if(!dfn[v]){ tarjan(v); low[u] = min(low[u],low[v]); }else if(in_stack[v]){ low[u] = min(low[u],dfn[v]); } } if(dfn[u] == low[u]){ ++scc; do{ belong[s[--top]] = scc; in_stack[s[top]] = false; }while(s[top] != u); } } int main() { int n,m; init(); cin>>n>>m; for(int i=0;i<m;i++){ int u,v; cin>>u>>v; insert(u,v); } memset(dfn,0,sizeof(dfn)); idx = 0; for(int i=1;i<=n;i++){ if(!dfn[i]){ tarjan(i); } } for(int i=1;i<=scc;i++){ cout<<"block "<<i<<": "; for(int j=1;j<=n;j++){ if(belong[j] == i){ cout<<j<<" "; } } cout<<endl; } return 0; }
題解地址:https://blog.csdn.net/qq_29980371/article/details/77963431ios
題解地址:https://blog.csdn.net/cillyb/article/details/72802229spa
G題:tarjan縮點,求出強連通份量,可是這樣作的人都wa了。。暫且先放在這篇博文裏,等時機成熟再補題。
.net
tarjan找最小環
https://www.luogu.org/problemnew/solution/P2661?page=2code
更多:http://www.javashuo.com/article/p-tajucyol-gy.html
求割點和橋:http://www.javashuo.com/article/p-wnuzutzi-ek.html
求割點和橋:https://www.jianshu.com/p/d765427e07df
加上兩句話:
if(dfn[u] <= low[v]) f = true;
if((!fa && son>1) || (fa && f)) cutp.push_back(u);htm
vector <int> cutp;//存放割點 void dfs(int u, int fa){ dfn[u] = low[u] = ++timer; int son = 0; bool f = false; for(int i=0;i<E[u].size();i++){ int v = E[u][i]; if(v == fa) continue; if(!dfn[v]){ son++; dfs(v, u); if(dfn[u] <= low[v]) f = true; low[u] = min(low[u], low[v]); } else low[u] = min(low[u], dfn[v]); } if((!fa && son>1) || (fa && f)) cutp.push_back(u); }