#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 105, maxm = maxn * 2; int n, m, tot, dfs_clock; int h[maxn], dfn[maxn], low[maxn], iscut[maxn]; struct edge { int v, next; }a[maxm]; void add(int x, int y) { a[tot].v = y; a[tot].next = h[x]; h[x] = tot++; } int dfs(int u, int fa) { int lowu = dfn[u] = ++dfs_clock;//注意这里一定是++dfs_clock,不然后来判断新搜到的节点有没有访问过就会出错。 int child = 0; for (int i = h[u]; ~i; i = a[i].next) { int v = a[i].v; if (!dfn[v])//如果这个节点我还没有访问过,树边 { child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if (lowv >= dfn[u]) { iscut[u] = 1; } if (lowv > dfn[u]) { printf("%d - %d ", u, v);//桥和割点的判断略有不同 } }else if (dfn[v] < dfn[u] && v != fa)//反向边 { lowu = min(lowu, dfn[v]); } } if (fa == 0 && child == 1)//排除根节点的特殊情况。 { iscut[u] = 0; } low[u] = lowu; return lowu; } int main() { freopen("无向图的割顶和桥.in","r",stdin); scanf("%d%d", &n, &m); memset(h, -1, sizeof h); tot = dfs_clock = 0; for (int i = 1; i <= m; i++) { int x, y; scanf("%d%d", &x, &y); add(x, y); add(y, x); } dfs(1, 0); for (int i = 1; i <= n; i++) if (iscut[i]) printf("%d ", i); return 0; }
现在力求代码规范,模板不错,所以这是照着白书打的,以前打的怎样都忘了就好。