poj1523 SPF【求割点,Targan算法】
解题报告参考《图论算法理论、实现及应用》 P390
View Code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN = 1000 + 10; int Edge[MAXN][MAXN]; int visited[MAXN]; int dfn[MAXN]; int low[MAXN]; int subnets[MAXN]; int nodes; //顶点数目。 int tmpdfn; //在dfs过程中记录当前的深度优先搜索序数。 int son; //根节点的子女节点的个数(如果大于2,则根节点是关节点). void dfs(int u) { for(int v = 1; v <= nodes; v++) { if( Edge[u][v] ) { if( !visited[v] ) { visited[v] = 1; tmpdfn++; dfn[v] = low[v] = tmpdfn; dfs( v ); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) { if(u != 1) { subnets[u]++; } if(u == 1) { son++; } } } else { low[u] = min(low[u], dfn[v]); } } } } void init() { low[1] = dfn[1] = 1; tmpdfn = 1; son = 0; memset(visited, 0, sizeof(visited)); visited[1] = 1; memset(subnets, 0, sizeof(subnets)); } int main() { int T = 1; while(1) { memset(Edge, 0, sizeof(Edge)); int u, v; scanf("%d", &u); if(u == 0) break; nodes = 0; scanf("%d", &v); if(u > nodes) nodes = u; if(v > nodes) nodes = v; Edge[u][v] = Edge[v][u] = 1; while(1) { scanf("%d", &u); if(u == 0) break; scanf("%d", &v); if(u > nodes) nodes = u; if(v > nodes) nodes = v; Edge[u][v] = Edge[v][u] = 1; } if(T > 1) printf("\n"); printf("Network #%d\n", T++); init(); dfs(1); if(son > 1) subnets[1] = son - 1; int find = 0; for(int i = 1; i <= nodes; i++) { if(subnets[i]) { find = 1; printf(" SPF node %d leaves %d subnets\n", i, subnets[i]+1); } } if(!find) printf(" No SPF nodes\n"); } return 0; }