图连通性模板

12 篇文章 0 订阅
8 篇文章 0 订阅

##有向图强连通缩点
####所需数组

i d x , l o w [ M A X N ] , d f n [ M A X N ] idx,low[MAXN],dfn[MAXN] idx,low[MAXN],dfn[MAXN]------------时间戳和两个访问标志
s c c n o , s c c [ M A X N ] sccno ,scc[MAXN] sccno,scc[MAXN] ————点属于哪个连通分支,及连通分量数量
s t a c k &lt; i n t &gt; s t , i n s t [ M A X N ] stack&lt;int&gt; st ,inst[MAXN] stack<int>st,inst[MAXN]————栈,一个中间工具,用于分辨点属于哪个连通分量
v e c t o r &lt; i n t &gt; G [ M A X N ] ; vector&lt;int&gt; G[MAXN]; vector<int>G[MAXN];————图

const int N = 40000;
const int M = 500000;

int head[N];
int top;
int n,m;
struct Edge
{
    int val;
    int to;
    int next;
}edge[M];
void addedge(int a,int b,int c)
{
    edge[top].to=b;
    edge[top].val=c;
    edge[top].next=head[a];
    head[a]=top++;
}
void init()
{
    top=0;
    for (int i=1;i<=n;i++)  head[i]=-1;
}

int idx,low[N],dfn[N];
int sccno,scc[N];
stack<int>st; int inst[N];
void tarjan_init(){
    init();
    clr(dfn,0);
    clr(inst,0);
    clr(scc,0);
    sccno=idx=0;
    while(!st.empty()) st.pop();

}

void tarjan(int x)
{
    low[x]=dfn[x]=++idx;
    st.push(x);
    inst[x]=1;
    for(int i=head[x];~i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[x]=min(low[v],low[x]);
        }
        else if(inst[v]){
            low[x]=min(low[x],dfn[v]);
        }
    }
    if(low[x]==dfn[x]){
        ++sccno;
        int v;
        while(1){
            v=st.top();
            st.pop();
            inst[v]=0;
            scc[v] = sccno;
            if(x==v) break;
        }
    }
}

##割边&&割点

//割点

const int N = 40000;
const int M = 500000;
int n,m;
int head[N];
int top;
struct Edge{
    int val;
    int to;
    int next;
}edge[M];
void addedge(int a,int b,int c)
{
    edge[top].to=b;
    edge[top].val=c;
    edge[top].next=head[a];
    head[a]=top++;
}
void init()
{
    top=0;
    for (int i=1;i<=n;i++)  head[i]=-1;
}
int low[N],dfn[N],idx;
int iscut[N];
int rootson;
void tarjan_init(){
    init();
    clr(dfn,0);
    idx=rootson=0;
    clr(iscut,0);

}


void tarjan(int u,int pre,int id){
    dfn[u]=low[u]=++idx;
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(i==(id^1)) continue;
        if(!dfn[v]){
            tarjan(v,u,i);
            if(u==1) rootson++;
            else {
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]) iscut[u]=1;
            }
        }else{
            low[u]= min(low[u],dfn[v]);
        }
    }
}
if(rootson>1) iscut[1]=1;//调用后 加一句

//割边
const int N = 40000;
const int M = 500000;
int n,m;

int head[N];
int top;
struct Edge{
    int val;
    int to;
    int next;
}edge[M];
void addedge(int a,int b,int c){
    edge[top].to=b;
    edge[top].val=c;
    edge[top].next=head[a];
    head[a]=top++;
}
void init()
{
    top=0;
    clr(head,-1);
}
int low[N],dfn[N],idx;
int fa[N],isbridge[N];
int bridge;

void tarjan_init()
{
    init();
    clr(dfn,0);
    bridge=idx=0;
    clr(isbridge,0);
    clr(fa,0);
}

void tarjan(int u,int pre,int id){
    fa[u]=pre;
    low[u]=dfn[u]=++idx;
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(i==(id^1)) continue; //......
        if(!dfn[v]){
            tarjan(v,u,i);
            low[u]=min(low[u],low[v]);
            if(low[v] > dfn[u]) {
                isbridge[v]=1,bridge++;
                //cout<<"isbridge"<<endl;
            }
        }
        else if(v!=pre){ //。。。。。
            low[u]=min(low[u],dfn[v]);
        }
    }
}
//注意isbridge数组与fa数组一起用,且若isbridge[i],则i和fa[i]是割边
//重边要不要注意写法

割边割点注意=号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值