[割点] poj 1523 SPF
来源:互联网 发布:mac没有管理员账户 编辑:程序博客网 时间:2024/05/01 11:24
/**[割点] poj 1523 SPF求割点及去掉该割点后的连通分量个数。dfn[] dfs产生的优先数low[u] 从u或u的子孙出发通过回边可以到达的最低深度优先数low[u] = min{dfn[u], min{low[w]|w是u的一个子女}, min{dfn[v]|v与u邻接且(u,v)是一条回边} }顶点u是割点的充要条件是: u 或者 是具有两个以上子女的深度优先生成树的根,或者虽不是一个根,但他有一个子女w使得low[w] >= dfn[u]*/#include <stdio.h>#include <string.h>#include <vector>#include <algorithm>using namespace std;#define N 1001vector<int> vec[N];int low[N],dfn[N],subnet[N],vis[N];int cnt,son,n;void dfs(int u){ for(int i = 0; i < vec[u].size(); ++i) { int v = vec[u][i]; if(!vis[v]) { vis[v] = 1; low[v] = dfn[v] = ++cnt; dfs(v); low[u] = min(low[v],low[u]); if(low[v] >=dfn[u]) { if(u == n) ++son; else ++subnet[u]; } } else low[u] = min(low[u],dfn[v]); }}void cutPoint(){ memset(subnet,0,sizeof(subnet)); memset(vis,0,sizeof(vis)); dfn[n] = low[n] = vis[n] = 1; cnt = 1; son = 0; dfs(n); if(son > 1) subnet[n] = son - 1; //if subnet[i] != 0 则i为割点且删除i后的连通分量个数为subnet[i] + 1 for(int i = 1; i <= n; ++i) vec[i].clear();}int main(){ int a,b,cas = 0; while(scanf("%d",&a) && a) { n = a; scanf("%d",&b); n = max(n,b); vec[a].push_back(b); vec[b].push_back(a); while(scanf("%d",&a) && a) { scanf("%d",&b); n = max(a,n); n = max(b,n); vec[a].push_back(b); vec[b].push_back(a); } cutPoint(); printf("Network #%d\n",++cas); int i,find = 0; for(i = 1; i <= n; ++i) if(subnet[i]) { find = 1; printf(" SPF node %d leaves %d subnets\n",i,subnet[i] + 1); } if(!find) printf(" No SPF nodes\n"); puts(""); } return 0;}