桥和割点

#include<bis/stdc++.h>
using namespace std;  
const int maxn=10000+10;  
typedef pair<int,int> Edge;   
int index=0,rootson=0;    
vector<bool> vis(maxn);      
vector<int> dfn(maxn),low(maxn),cutvex;  
vector<vector<int> > G(maxn);    
vector<Edge> bridge;  
void Tarjan(int u,int father){  
    dfn[u]=low[u]=++index;  
    vis[u]=true;  
    bool isCut=false;  
    for(int i=0;i<G[u].size();i++){  
        int v=G[u][i];  
        if(!vis[v]){  
            Tarjan(v,u);  
            low[u]=min(low[u],low[v]);  
            if(dfn[u]<low[v])bridge.push_back(Edge(u,v));  
            if(dfn[u]<=low[v]) isCut=true;  
        }  
        else if(father!=v) //只能由非父子边更新   
            low[u]=min(low[u],dfn[v]);  
    }  
    if(father==1&&rootson!=-1) rootson++;  
    if(rootson>1) cutvex.push_back(1),rootson=-1;   
    if(u!=1&&isCut) cutvex.push_back(u);  
}  
int main(){  
    int n,m;cin>>n>>m;  
    while(m--){  
        int u,v;cin>>u>>v;  
        G[u].push_back(v);  
        G[v].push_back(u);  
    }  
    Tarjan(1,0);  //联通的  
    sort(cutvex.begin(),cutvex.end());  
    sort(bridge.begin(),bridge.end());  
    for(int i=0;i<cutvex.size();i++)  
        cout<<cutvex[i]<<endl;  
    for(int i=0;i<bridge.size();i++)  
        cout<<bridge[i].first<<','<<bridge[i].second<<endl;  
    return 0;  
} 
桥和割点

定义:
割点:无向连通图中,如果删除某点后,图变成不连通,则称该点为割点。
桥:无向连通图中,如果删除某边后,图变成不连通,则称该边为桥。

题意:
给你一些点,某些点之间有边。求有多少个点是割点

变量:
low[u]定义为u或者u的子树中能够通过非父子边追溯到的最早的节点的DFS开始时间
dfn[u]表示dfs下u的开始时间

判断割点方法:
(1) u为树根,且u有多于一个子树。
(2) u不为树根,且存在(u,v)为树枝边(或称父子边,即u为v在搜索树中的父亲),使得dfn(u)<=low(v)。也就是u的子树中的v点无法到达u之前的点,所以u点去掉就是两个连通分支,所以u为割点

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值