参考:https://blog.csdn.net/wtyvhreal/article/details/43530613
因为我是用邻接表写的,所以时间复杂度:O(n+m);
求割点模板:
(前向星):
#include
#define ll long long
#define endl '\n'
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=2e5+10;
ll root;
ll dfn[maxn],low[maxn],tott,n,m,ans=-1,vis[maxn],flag[maxn];
stack<ll> s;
ll tot;ll head[maxn];ll fa[maxn];
struct E{
ll to,next;
}edge[maxn<<1];
void add(ll u,ll v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void tarjan(ll x){
ll child=0;
low[x]=dfn[x]=++tott;
for(ll i=head[x];i!=-1;i=edge[i].next){
ll v=edge[i].to;
if(!dfn[v]){
child++;fa[v]=x;
tarjan(v);
low[x]=min(low[x],low[v]);
if(fa[x]!=-1&&low[v]>=dfn[x]) flag[x]=1;
if(fa[x]==-1&&child>=2) flag[x]=1;
}else if(v!=fa[x]){
low[x]=min(low[x],dfn[v]);
}
}
}
int main(){
cin>>n>>m;
memset(head,-1,sizeof(head));
memset(fa,-1,sizeof(fa));
for(ll i=1;i<=m;i++){
ll u,v;cin>>u>>v;
add(u,v);add(v,u);
}
for(ll i=1;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
cout<<endl;
for(ll i=1;i<=n;i++){
if(flag[i]) cout<<i<<" ";
}
}
/*
7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
*/
非前向星:
#include
#define ll long long
#define endl '\n'
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=2e5+10;
vector<ll> edge[maxn];
ll root;
ll dfn[maxn],low[maxn],tot,n,m,ans=-1,vis[maxn],flag[maxn];
stack<ll> s;
void tarjan(ll x,ll father){
ll child=0;
low[x]=dfn[x]=++tot;
s.push(x);vis[x]=1;
for(ll i=0;i<edge[x].size();i++){
ll v=edge[x][i];
if(!dfn[v]){
child++;
tarjan(v,x);
low[x]=min(low[x],low[v]);
if(x!=root&&low[v]>=dfn[x]) flag[x]=1;
if(x==root&&child==2) flag[x]=1;
}else if(v!=father){
low[x]=min(low[x],dfn[v]);
}
}
}
int main(){
cin>>n>>m;
for(ll i=1;i<=m;i++){
ll u,v;cin>>u>>v;
edge[u].push_back(v);
edge[v].push_back(u);
}
root=1;
for(ll i=1;i<=n;i++){
if(!dfn[i]) tarjan(i,root);
}
cout<<endl;
for(ll i=1;i<=n;i++){
if(flag[i]==1) cout<<i<<" ";
}
}
/*
7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
*/
求桥模板:
前向星:
#include
#define ll long long
#define endl '\n'
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=2e5+10;
ll root;
ll dfn[maxn],low[maxn],tott,n,m,ans=-1,vis[maxn],flag[maxn];
stack<ll> s;
ll tot;ll head[maxn];ll fa[maxn];
struct E{
ll to,next;
}edge[maxn<<1];
void add(ll u,ll v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void tarjan(ll x){
ll child=0;
low[x]=dfn[x]=++tott;
for(ll i=head[x];i!=-1;i=edge[i].next){
ll v=edge[i].to;
if(!dfn[v]){
child++;fa[v]=x;
tarjan(v);
low[x]=min(low[x],low[v]);
if(low[v]>dfn[x]) {cout<<x<<"->"<<v<<endl;}
}else if(v!=fa[x]){
low[x]=min(low[x],dfn[v]);
}
}
}
int main(){
cin>>n>>m;
memset(head,-1,sizeof(head));
memset(fa,-1,sizeof(fa));
for(ll i=1;i<=m;i++){
ll u,v;cin>>u>>v;
add(u,v);add(v,u);
}
for(ll i=1;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
}
/*
7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
*/
非前向星
#include
#define ll long long
#define endl '\n'
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=2e5+10;
vector<ll> edge[maxn];
ll root;
ll dfn[maxn],low[maxn],tot,n,m,ans=-1,vis[maxn],flag[maxn];
stack<ll> s;
void tarjan(ll x,ll father){
low[x]=dfn[x]=++tot;
s.push(x);vis[x]=1;
for(ll i=0;i<edge[x].size();i++){
ll v=edge[x][i];
if(!dfn[v]){
tarjan(v,x);
low[x]=min(low[x],low[v]);
if(low[v]>dfn[x]) printf("%d-%d\n",x,v);
}else if(v!=father){
low[x]=min(low[x],dfn[v]);
}
}
}
int main(){
cin>>n>>m;
for(ll i=1;i<=m;i++){
ll u,v;cin>>u>>v;
edge[u].push_back(v);
edge[v].push_back(u);
}
root=1;
for(ll i=1;i<=n;i++){
if(!dfn[i]) tarjan(i,root);
}
}
/*
7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
*/