代碼直接整合了求割點和割邊:
//求無向連通圖的割點和割邊/橋#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define MAXN 1000#define MAXM 10000struct node{ int to; int next;}edge[MAXM];int head[MAXN];int cnt;int n,m;int index;//時間戳int cut[MAXN];//存割點int bridge[MAXN][MAXN];//存割邊int dfn[MAXN],low[MAXN];//dfn:時間戳;low:可以到達的 訪問時間最早的 祖先(訪問時間比自己早的節點看作自己的祖先)void Init(){ cnt=0; index=0; memset(head,0,sizeof(head)); memset(edge,0,sizeof(edge)); memset(cut,0,sizeof(cut)); memset(bridge,0,sizeof(int)*MAXN*MAXN); memset(dfn,0,sizeof(dfn));}void Add(int x,int y){ cnt++; edge[cnt].to=y; edge[cnt].next=head[x]; head[x]=cnt;}void cut_bridge(int cur,int father){ int child=0; index++; dfn[cur]=index; low[cur]=index; for(int i=head[cur];i;i=edge[i].next){ if(dfn[edge[i].to]&&edge[i].to!=father){ if(dfn[edge[i].to]<low[cur]){ low[cur]=dfn[edge[i].to]; } } if(!dfn[edge[i].to]){ cut_bridge(edge[i].to,cur);//可以看出,具體搜索的過程還是下一步走未訪問的點 child++; if(low[edge[i].to]<low[cur]){ low[cur]=low[edge[i].to]; } if((father==0&&child>1)||(father!=0&&low[edge[i].to]>=dfn[cur])){ cut[cur]=1; } if(low[edge[i].to]>dfn[cur]){ bridge[cur][edge[i].to]=bridge[edge[i].to][cur]=1; } } }}int main(){ int x,y; freopen("1.txt","r",stdin); cin>>n>>m; Init(); for(int i=1;i<=m;i++){ cin>>x>>y; Add(x,y); Add(y,x); } cut_bridge(1,0); return 0;}對于非連通圖,對于每個連通分量取一個點調用cut_bridge()函數即可
新聞熱點
疑難解答