zoukankan      html  css  js  c++  java
  • Tarjan模板大全

    点双连通分量

    #include<iostream>
    #include<vector>
    #include<stack>
    using namespace std;
    int n,m,t,ans;
    int dfn[100001],low[100001],sum,in;
    vector<int>gcc[100001],g[100001];
    stack<int>s;
    void tarjan(int u,int fa) {
    	dfn[u]=low[u]=++in;
    	if(fa==-1&&g[u].size()==0){
    		gcc[u].push_back(++sum);
    		return;
    	}
    	s.push(u);
    	for(int i=0; i<g[u].size(); i++) {
    		int v=g[u][i];
    		if(v==fa)continue;
    		if(!dfn[v]) {
    			tarjan(v,u);
    			low[u]=min(low[u],low[v]);
    			if(low[v]>=dfn[u]){
    				sum++;
    				int d;
    				do{
    					d=s.top();
    					s.pop();
    					gcc[d].push_back(sum);
    				}while(d!=v);
    				gcc[u].push_back(sum);
    			}
    		} else {
    			low[u]=min(low[u],dfn[v]);
    		}
    	}
    }
    int main() {
    	cin>>n>>m;
    	while(m--) {
    		int x,y;
    		cin>>x>>y;
    		g[x].push_back(y);
    		g[y].push_back(x);
    	}
    	for(int i=1; i<=n; i++) {
    		if(!dfn[i])tarjan(i,-1);
    	}
    	return 0;
    }
    

    边双连通分量

    #include<iostream>
    #include<cstring>
    using namespace std;
    struct ed {
    	int to,next;
    } a[1000001];
    int head[300001];
    int n,m,q,t,ans;
    int dfn[300001],low[300001],scc[300001],cnt,in;
    bool vis[1000001];
    void tarjan(int u,int fa) {
    	dfn[u]=low[u]=++in;
    	for(int i=head[u]; i!=-1; i=a[i].next) {
    		if((i^1)==fa)continue;
    		int v=a[i].to;
    		if(!dfn[v]) {
    			tarjan(v,i);
    			low[u]=min(low[u],low[v]);
    			if(low[v]>dfn[u]){
    				vis[i]=vis[i^1]=true;
    			}
    		} else {
    			low[u]=min(low[u],dfn[v]);
    		}
    	}
    }
    void dfs(int u) {
    	scc[u]=cnt;
    	for(int i=head[u]; i!=-1; i=a[i].next) {
    		int v=a[i].to;
    		if(!scc[v]&&!vis[i])dfs(v);
    	}
    }
    void add(int u,int v) {
    	a[t].to=v;
    	a[t].next=head[u];
    	head[u]=t++;
    }
    int main() {
    	cin>>n>>m>>q;
    	memset(head,-1,sizeof(head));
    	while(m--) {
    		int x,y;
    		cin>>x>>y;
    		add(x,y),add(y,x);
    	}
    	for(int i=1; i<=n; i++) {
    		if(!dfn[i])tarjan(i,-1);
    	}
    	for(int i=1; i<=n; i++) {
    		cnt++;
    		if(!scc[i])dfs(i);
    	}
    	return 0;
    }
    
    

    #include<iostream>
    #include<cstring>
    #include<vector>
    using namespace std;
    struct ed {
    	int to,next;
    } a[200001];//edge*2
    int head[100001];
    int n,m,in,dfn[100001],low[100001];
    bool vis[100001];
    void tarjan(int u,int fa) {
    	dfn[u]=low[u]=++in;
    	for(int i=head[u]; i!=-1; i=a[i].next) {
    		if((i^1)==fa)continue;
    		int v=a[i].to; 
    		if(!dfn[v]) {
    			tarjan(v,u);
    			low[u]=min(low[u],low[v]);
    			if(low[v]>dfn[u])vis[i]=vis[i^1]=true;
    		} else {
    			low[u]=min(low[u],dfn[v]);
    		}
    	}
    }
    int main() {
    	cin>>n>>m;
    	while(m--) {
    		int u,v;
    		cin>>u>>v;
    		add(u,v),add(v,u);
    	}
    	for(int i=1;i<=n;i++){
    		if(!dfn[i])tarjan(i,-1);
    	}
    	return 0;
    }
    

    割点

    #include<iostream>
    #include<cstring>
    #include<vector>
    using namespace std;
    bool vis[10001];
    int n,m,in,sum,dfn[10001],low[10001],cnt[10001];
    vector<int>g[10001];
    void tarjan(int u,int fa) {
    	dfn[u]=low[u]=++in;
    	int c=0;
    	for(int i=0; i<g[u].size(); i++) {
    		int v=g[u][i];
    		if(v==fa)continue;
    		if(!dfn[v]) {
    			c++;
    			tarjan(v,u);
    			low[u]=min(low[u],low[v]);
    			if(low[v]>=dfn[u])iscp=true;
    		} else {
    			low[u]=min(low[u],dfn[v]);
    		}
    	}
    	if(fa==-1&&c<=1)iscp[u]=false;
    }
    int main() {
    	cin>>n>>m;
    	while(m--) {
    		int u,v;
    		cin>>u>>v;
    		g[u].push_back(v);
    		g[v].push_back(u);
    	}
    	for(int i=1; i<=n; i++) {
    		if(!dfn[i])tarjan(i,-1);
    	}
    	return 0;
    }
    

    强连通分量

    #include<iostream>
    #include<vector>
    #include<stack>
    using namespace std;
    vector<int> g[10001];
    int n,m,x,y,dfn[10001],low[10001],scc[10001],cnt,index;
    stack<int> st;
    void tarjan(int u){
    	dfn[u]=low[u]=++index;
    	st.push(u);
    	for(int i=0;i<g[u].size();i++){
    		int v=g[u][i];
    		if(!dfn[v]){
    			tarjan(v);
    			low[u]=min(low[u],low[v]);
    		}else{
    			if(!scc[v])low[u]=min(low[u],dfn[v]);
    		}
    	}
    	if(dfn[u]==low[u]){
    		cnt++;
    		int v;
    		do{
    			v=st.top();
    			st.pop();
    			scc[v]=cnt;
    		}while(u!=v);
    	}
    }
    int main(){
    	cin>>n>>m;
    	for(int i=1;i<=m;i++){
    		cin>>x>>y;
    		g[x].push_back(y);
    	}
    	for(int i=1;i<=n;i++){
    		if(!dfn[i])tarjan(i);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    关于HashMap的线程安全问题
    Java利器之UML类图详解
    mongoDB4.0数据库
    requests-html库render的使用
    爬虫最新的库requests-html库总结
    爬虫多次爬取时候cookie的存储用于登入
    requests模块响应体属性和方法重新整理
    Visual Studio 代码补全功能有时候会失效的原因
    C++Primer笔记——文本查询程序(原创,未使用类)
    Clion 常用快捷键
  • 原文地址:https://www.cnblogs.com/ezlmr/p/13573446.html
Copyright © 2011-2022 走看看