标签:
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