[割点] poj 1523 SPF
2012-08-14 23:44
399 查看
/** [割点] 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 1001 vector<int> vec ; int low ,dfn ,subnet ,vis ; 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 = low = vis = 1; cnt = 1; son = 0; dfs(n); if(son > 1) subnet = 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; }
相关文章推荐
- poj1523 SPF 双连通求割点
- poj1523 SPF
- 【poj 1523】SPF 【Greater New York 2000】
- poj 1523 SPF
- POJ 1523 SPF 找割点
- POJ 1523 SPF 割点
- [学习][poj1523]割点 SPF
- POJ1523:SPF——题解
- 【POJ】1523 SPF 割点
- POJ--1523 SPF(割点)
- POJ1523 SPF(割点模板)
- POJ 1523 SPF(无向图连通分量求割点)
- POJ 1523 SPF
- POJ1523 SPF
- POJ 1523 SPF 求割点
- POJ1523 SPF 求割点及连通块数 tarjin算法
- POJ 1523 SPF 求割点的好(板子)题!
- POJ 1523 SPF(求割点)
- poj 1523 SPF 输出割点及割点分割的点集数目
- POJ 1523 SPF 无向图求割点