#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 7500
#define inf 0x3f3f3f3f
int first[maxn],to[maxn],nxt[maxn],e;
int pre[maxn],low[maxn];
int clock;
int iscut[maxn];
void add(int u,int v){
to[e]=v;nxt[e]=first[u];first[u]=e++;
}
int dfs1(int u,int fa){
low[u]=pre[u]=++clock;
for(int i=first[u];~i;i=nxt[i]){
int v=to[i];
if(!pre[v]){
low[u]=min(low[u],dfs1(v,u));
}
else if(pre[v]<pre[u]&&v!=fa){
low[u]=min(low[u],pre[v]);
}
}
return low[u];
}
int n,m,t;
int g[maxn][maxn];
struct edge{
int u,v;
edge(int u,int v):u(u),v(v){};
edge(){};
}bridge[maxn];
int dfs(int u,int fa){
low[u]=pre[u]=++clock;
for(int v=1;v<=n;v++){
if(g[u][v]){
if(!pre[v]){
int lowv=dfs(v,u);
low[u]=min(low[u],lowv);
if(lowv>=pre[u]){
iscut[u]=1;
}
if(lowv>pre[u]){
bridge[t++]=edge(u,v);
}
}
else if(pre[v]<pre[u]&&v!=fa){
low[u]=min(low[u],pre[v]);
}
}
}
if(fa<0)iscut[u]=0;
return low[u];
}
void inital(){
t=0;
e=0;
clock=0;
memset(first,-1,sizeof first);
memset(pre,0,sizeof pre);
for(int i=1;i<=n;i++){
low[i]=10000;
}
}
int main()
{
int u,v;
freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m)){
inital();
for(int i=0;i<m;i++){
scanf("%d%d",&u,&v);
//add(u,v);
//add(v,u);
g[u][v]=g[v][u]=1;
}
for(int i=1;i<=n;i++){
if(!pre[i])dfs(i,-1);
}
for(int i=1;i<=n;i++){
printf("%d %d\n",pre[i],low[i]);
}
for(int i=1;i<=n;i++){
printf("%d ",iscut[i]);
}
printf("\n下面是桥:\n");
for(int i=0;i<t;i++){
printf("%d -> %d\n",bridge[i].u,bridge[i].v);
}
printf("\n");
}
}
无向图的割顶和桥(tarjan模板)
最新推荐文章于 2021-09-19 16:29:12 发布