tarjan 求强连通分量模板

来源:互联网 发布:杭州行知中学校园网 编辑:程序博客网 时间:2024/05/27 00:35
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>#include <queue>#include <stack>using namespace std;const int inf =0x3ffffff;const int maxn=10005;//点数struct edge{    int from,to,w,next;}e[50005];//边数stack<int>pq;int head[maxn];int instack[maxn];//是否在栈中int dfn[maxn];//同时可用于判断是否遍历过int low[maxn];int n,m,t,index;//n个点,m条边,t用来生成边的标号,index用来生成点的标号void init()//建图前运行init{t=0;index=0;    memset(head,-1,sizeof(head));memset(instack,0,sizeof(instack));memset(dfn,-1,sizeof(dfn));memset(low,-1,sizeof(low));while(!pq.empty())pq.pop();}void add(int i,int j,int w){    e[t].from=i;    e[t].to=j;    e[t].w=w;    e[t].next=head[i];    head[i]=t++;}void tarjan(int u){dfn[u]=low[u]=++index;pq.push(u);instack[u]=1;for(int i=head[u];i!=-1;i=e[i].next){if(dfn[e[i].to]==-1){tarjan(e[i].to);low[u]=min(low[u],low[e[i].to]);}else if(instack[e[i].to]==1){low[u]=min(low[u],dfn[e[i].to]);}}if(dfn[u]==low[u]){int v;v=pq.top();//从这个v开始为强连通分量的一个//solve vpq.pop();instack[v]=0;while(v!=u){v=pq.top();//solve vpq.pop();instack[v]=0;}}}int main(){    int a,b;int i,j;    scanf("%d%d",&n,&m);init();    while(m--)    {        scanf("%d%d",&a,&b);        add(a,b,0);    }for(i=1;i<=n;i++){if(dfn[i]==-1)tarjan(i);}    return 0;}

0 0
原创粉丝点击