poj 1523 求割点
题意:是求一个无向图的割点,和连通子图个数。
根据割点定义:
1. u为根, 则u至少有两个儿子。
2. u不为根,则至少存在某一儿子节点s, low[s] >= d[u], 即s和s的后代不会追溯到比u更早的祖先点。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<iostream> #include<vector> #include<string> #include<math.h> #include<map> #include<set> #include<algorithm> using namespace std; #define MAXN 1000100 struct Edge { int u, next; Edge( ) { } Edge( int U, int Next) : u(U), next(Next) { } }edge[MAXN]; int head[MAXN], e, ptime, N; int d[1010], low[1010], cut[1010], cnt; void init( ) { memset(head, -1, sizeof(head)); e = 0; ptime = 0; memset(d, 0, sizeof(d)); memset(low,0,sizeof(low)); memset(cut,0,sizeof(cut)); } void AddEdge( int u, int v) { edge[e]= Edge(v, head[u]); head[u] = e++; edge[e] = Edge(u, head[v]); head[v] = e++; } //找割点 void find_cut( int u ) { low[u] = d[u] = ++ptime; int son = 0; for( int e = head[u]; e != -1; e = edge[e].next ) { int v = edge[e].u; if( !d[v] ) { son++; find_cut( v ); if( (u != 1 && low[v] >= d[u]) || (u == 1) && son >= 2 ) cut[u]++; low[u] = min(low[u], low[v]); } else { low[u] = min( low[u], d[v]); } } } void solve( ) { find_cut(1); bool f = false; for( int i = 1; i <= N; i++) { if( cut[i] ) printf(" SPF node %d leaves %d subnets\n", i, cut[i] + 1), f = true; } if( !f ) puts(" No SPF nodes"); puts(""); } int main( ) { int a, b, abc = 1; while( scanf("%d", &a) != EOF ) { init( ); if( a == 0 ) break; scanf("%d",&b); while( 1 ) { AddEdge(a, b); N = max(N, max(a,b)); scanf("%d",&a); if( a == 0 ) break; scanf("%d",&b); } printf("Network #%d\n", abc++); solve( ); } return 0; }
posted on 2012-09-24 12:11 more think, more gains 阅读(122) 评论(0) 编辑 收藏 举报