POJ 1144
2014-04-30 18:37
274 查看
思路:求割点
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int v = 105; int edge[v][v]; int bridge[v][v], cut[v]; int low[v], dfn[v], vis[v]; void cut_bridge(int cur, int father, int dep, int n){ vis[cur] = 1;dfn[cur] = low[cur] = dep; int children = 0; for(int i = 0;i < n;i ++) if(edge[cur][i]){ if(i != father && 1 == vis[i]){ if(dfn[i] < low[cur]) low[cur] = dfn[i]; } if(0 == vis[i]){ cut_bridge(i, cur, dep+1, n); children ++; if(low[i] < low[cur]) low[cur] = low[i]; if((father == -1 && children > 1) || (father != -1 && low[i] >= dfn[cur])) cut[cur] = 1; } if(low[i] > dfn[cur]) bridge[i][cur] = bridge[cur][i] = 1; } vis[cur] = 2; } int main(){ int n, temp, u; /* freopen("in.c", "r", stdin); */ while(~scanf("%d", &n) && n){ memset(vis, 0, sizeof(vis)); memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(cut, 0, sizeof(cut)); memset(edge, 0, sizeof(edge)); scanf("%d", &temp); while(temp){ while(getchar() != '\n'){ scanf("%d", &u); edge[u-1][temp-1] = edge[temp-1][u-1] = 1; } scanf("%d", &temp); } int ans = 0; cut_bridge(1, -1, 0, n); for(int i = 0;i < n;i ++ ){ if(cut[i]) ans ++; } printf("%d\n", ans); } return 0; }