首页 > 代码库 > Tarjan 割点割边【模板】

Tarjan 割点割边【模板】

 1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4  5 using namespace std; 6  7 const int N(100000+15); 8 int n,m,u,v; 9 int head[N],sumedge;10 struct Edge11 {12     int to,next;13     Edge(int to=0,int next=0) :14         to(to),next(next){}15 }edge[N<<1];16 17 void ins(int from,int to)18 {19     edge[++sumedge]=Edge(to,head[from]);20     head[from]=sumedge;21 }22 23 int dfn[N],low[N],tim;24 int cutpoint[N],cutedge[N],sum;25 26 void DFS(int now,int pre)27 {28     low[now]=dfn[now]=++tim;29     int sumtredge=0,if_cutpoint=0;30     for(int i=head[now];i!=-1;i=edge[i].next)31         if((i^1)!=pre)32         {33             int go=edge[i].to;34             if(!dfn[go])35             {36                 sumtredge++;37                 DFS(go,i);38                 if(low[go]>=dfn[now]) if_cutpoint=1;39                 if(low[go]>dfn[now]) cutedge[i>>1]=true;40                 low[now]=min(low[now],low[go]);41             }42             else low[now]=min(low[now],dfn[go]);43           }44     if(pre==-1)45     {46         if(sumtredge>1)  cutpoint[now]=true;47     }48     else if(if_cutpoint) cutpoint[now]=true;49 }50 51 int main()52 {53     /*freopen("made.txt","r",stdin);54     freopen("myout.txt","w",stdout);*/55     56     scanf("%d%d",&n,&m);57     sumedge=-1; //使边之间更有关系58     memset(head,-1,sizeof(head));59     for(int i=1;i<=m;i++)60     {61         scanf("%d%d",&u,&v);62         ins(u,v);63         ins(v,u);64     }65     for(int i=1;i<=n;i++) 66         if(!dfn[i]) DFS(i,-1);67     for(int i=1;i<=n;i++)68         if(cutpoint[i]) printf("%d ",i);69     printf("\n");70     for(int i=0;i<sumedge;i++)71         if(cutedge[i]) printf("%d ",i);72     return 0;73 }

 

Tarjan 割点割边【模板】