标签:
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 7066 | Accepted: 3218 |
Description

Input
Output
Sample Input
1 2 5 4 3 1 3 2 3 4 3 5 0 1 2 2 3 3 4 4 5 5 1 0 1 2 2 3 3 4 4 6 6 3 2 5 5 1 0 0
Sample Output
Network #1 SPF node 3 leaves 2 subnets Network #2 No SPF nodes Network #3 SPF node 2 leaves 2 subnets SPF node 3 leaves 2 subnets
Source
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#define maxn 1000+10
#define maxm 2000000+10
using namespace std;
struct node {
int u, v, next;
};
node edge[maxm];
int head[maxn], cnt;
int low[maxn];//从该点或它的子孙出发 通过回边可以到达的最低
int dfn[maxn];//该点的深度优先数
bool is_cut[maxn];//标记该点是不是割点
int add_bcc[maxn];//去掉该点增加的bcc数目
int dfs_clock;//深度优先数计数器
int bccno[maxn];//属于哪个bcc
int bcc_cnt;//bcc计数器
stack<node> S;//存储当前bcc中的边
vector<int>bcc[maxn];//存储bcc里面的点
void init(){
cnt = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v){
edge[cnt] = {u, v, head[u]};
head[u] = cnt++;
edge[cnt] = {v, u, head[v]};
head[v] = cnt++;
}
int tarian(int u, int fa){
low[u] = dfn[u] = ++dfs_clock;
int son = 0;
for(int i = head[u]; i != -1; i = edge[i].next){
node E = edge[i];
int v = E.v;
if(!dfn[v]){
S.push(E);
son++;
low[v] = tarian(v, u);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u]){ // u 是割点,但不是根节点
is_cut[u] = true;
//记录 u 有几个满足low[v] >= dfn[u]的子节点 v,
//若有d个,去掉该割点后分成了 d + 1个连通分量。(这个 + 1会在后面输出的时候加上)
add_bcc[u]++;
//记录bcc里面的点
bcc_cnt++;
bcc[bcc_cnt].clear();
while(1){
node A = S.top();
S.pop();
if(bccno[A.u] != bcc_cnt){
bcc[bcc_cnt].push_back(A.u);
bccno[A.u] = bcc_cnt;
}
if(bccno[A.v] != bcc_cnt){
bcc[bcc_cnt].push_back(A.v);
bccno[A.v] = bcc_cnt;
}
if(A.u == u && A.v == v) break;
}
}
}
else if(v != fa && dfn[v] < dfn[u]){
S.push(E);
low[u] = min(low[u], dfn[v]);//回边更新
}
}
//u 是根节点, 但它的子节点只有一个,不是割点
if(fa < 0 && son == 1) is_cut[u] = 0;
//u 是根节点, 而且它的子节点个数 >= 2,是割点。删去该点后
//u 有几个子节点, 就分成了几个bcc, 这里 先 son - 1, 后面输出的时候会 + 1.
if(fa < 0 && son > 1) add_bcc[u] = son - 1;
return low[u];
}
void find(int l, int r){
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(add_bcc, 0, sizeof(add_bcc));
memset(is_cut, 0, sizeof(is_cut));
memset(bccno, 0, sizeof(bccno));
dfs_clock = bcc_cnt = 0;
for(int i = l; i <= r; ++i)
if(!dfn[i]) tarian(i, -1);
}
int main (){
int l, r;
int a, b;
int k = 1;
while(1){
init();
l = 2000, r = 0;
scanf("%d", &a);
if(a == 0) return 0;
l = min(a, l);
r = max(a, r);
scanf("%d", &b);
l = min(b, l);
r = max(b, r);
addedge(a, b);
while(scanf("%d", &a), a){
l = min(a, l);
r = max(a, r);
scanf("%d", &b);
l = min(b, l);
r = max(b, r);
addedge(a, b);
}
find(l, r);
int flag = 0;
printf("Network #%d\n", k++);
for(int i = l; i <= r; ++i){
if(is_cut[i]){
flag = 1;
printf(" SPF node %d leaves %d subnets\n", i, add_bcc[i] + 1);
}
}
if(!flag)
printf(" No SPF nodes\n");
printf("\n");
}
return 0;
}
void BCC(){
printf("have %d BCC(s)\n", bcc_cnt);
for(int i = 1; i <= bcc_cnt; i++){
printf("BCC %d have node(s): ", i);
for(int j = 0; j < bcc[i].size(); j++)
printf("%d ", bcc[i][j]);
printf("\n");
}
} 版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 1523--SPF【无向图的所有割点 && 删去该点后bcc的数目】
标签:
原文地址:http://blog.csdn.net/hpuhjh/article/details/47446985