用邻接矩阵写的。自己慢慢理解吧
#include <iostream> #include <cstring> using namespace std; #define CC(c) memset(c, 0, sizeof(c)) const int maxn=5000; int iscut[maxn], g[maxn][maxn], low[maxn], pre[maxn], _pre, n, m; int dfs(int u, int fa) { low[u]=pre[u]=++_pre; //初始时 int child=0; //如果child=1并且它是根,就不是割顶 for(int v=1; v<=n; ++v) if(g[u][v]) { if(!pre[v]) { child++; int lowv=dfs(v, u); //找子女的最小low,看是否能回溯到自己的fa前面 if(lowv<low[u]) low[u]=lowv; //更新最小 if(lowv>=pre[u]) iscut[u]=1; //如果在fa后面,即没有指向fa前面,就是一个割顶 } else if(pre[v]<pre[u] && v!=fa && low[u]>pre[v]) //因为是无向图,所以要判断是否是之前的访问的第二次访问回去的环 low[u]=pre[v]; } if(fa<0 && child==1) iscut[u]=0; return low[u]; } void find_cut() { CC(iscut); CC(low); CC(pre); for(int i=1; i<=n; ++i) if(!pre[i]) dfs(i, -1); for(int i=1; i<=n; ++i) if(iscut[i]) cout << i << " "; cout << endl; } int main() { cin >> n >> m; for(int i=1; i<=n; ++i) { int a, b; cin >> a >> b; g[a][b]=g[b][a]=1; } find_cut(); return 0; }
原文地址:http://www.cnblogs.com/iwtwiioi/p/3834731.html