/* ggg ggg ggggggg ggggggg ggggggggggggggggggg ggggggggggggggg ggggggggggg ggggggg ggg g */ /* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 500+5; const ll maxm = 1e7; const int mod = 1e9 + 7; const int INF = 0x3f3f3f; const ll inf = 1e15 + 5; const db eps = 1e-9; #define N 201 vector<int>G[N]; int n,m,low[N],dfn[N]; bool is_cut[N]; int father[N]; int tim=0; void init() { memset(dfn, -1, sizeof(dfn)); memset(father, 0, sizeof(father)); memset(low, -1, sizeof(low)); memset(is_cut, 0, sizeof(is_cut)); } void Tarjan(int i, int Father) { father[i] = Father; dfn[i] = low[i] = tim++; for (int j = 0; j < G[i].size(); j++) { int k = G[i][j]; if (dfn[k]==-1) { Tarjan(k, i); low[i] = min(low[i], low[k]); } else if(Father != k) { low[i] = min(low[i], dfn[k]); } } } void cnt() { int rootson=0; Tarjan(1, 0); for(int i=2;i<=n;++i){ int v=father[i]; if(v==1) rootson++;/*统计根节点子树的个数,根节点的子树个数>=2,就是割点*/ else{ if(low[i]>=dfn[v])/*割点的条件*/ is_cut[v]=true; } } if(rootson>1) is_cut[1]=true; for(int i=1;i<=n;++i) if(is_cut[i]) printf("%d\n",i); for(int i=1;i<=n;++i){ int v=father[i]; if(v>0&&low[i]>dfn[v])/*桥的条件*/ printf("%d,%d\n",v,i); } } void solve() { init(); // scanf("%d%d", &n, &m); cin >> n >> m; for (int i = 0; i < N; i++) G[i].clear(); for (int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); G[a].push_back(b); G[b].push_back(a); } int rootson=0; cnt(); } int main() { int t = 1; //scanf("%d", &t); while(t--) solve(); return 0; }
原文:http://www.cnblogs.com/gggyt/p/6411538.html