POJ1523(求割点)

割点:删掉它之后(删掉所有跟它相连的边),图必然会分裂成两个或两个以上的子图。

一个顶点u是割点,当且仅当满足(1)或(2)
(1) u为树根,且u至少有两个子女
(2) u不为树根,且满足存在(u,v)为树枝边(或称父子边,即u为v在搜索树中的父亲),使得low[v]>=dfn[u]

dfn[i]表示DFS 过程中到达点i 的时间,low[i]表示能通过其他边回到其祖先的最早时间

 

邻接表版本

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 #define N 1005
 8 #define M 100000
 9 struct Edge
10 {
11     int v,next;
12     Edge(){}
13     Edge(int V,int NEXT):v(V),next(NEXT){}
14 }edge[M];
15 int size,head[N];
16 int nodes,son,index;
17 int dfn[N],low[N],subnets[N];
18 void Init()
19 {
20     nodes = son = 0;
21     size = index = 0;
22     memset(subnets,0,sizeof(subnets));
23     memset(head,-1,sizeof(head));
24     memset(dfn,0,sizeof(dfn));
25     memset(low,0,sizeof(low));
26 }
27 void InsertEdge(int u,int v)
28 {
29     edge[size] = Edge(v,head[u]);
30     head[u] = size++;
31 }
32 void Trajan(int u)
33 {
34     low[u] = dfn[u] = ++index;
35     for(int i=head[u]; i!=-1; i=edge[i].next)
36     {
37         int v = edge[i].v;
38         if(!dfn[v])
39         {
40             Trajan(v);
41             low[u] = min(low[u],low[v]);
42             if(low[v] >= dfn[u])
43             {
44                 if(u != 1) subnets[u]++;
45                 if(u == 1) son++;
46             }
47         }
48         else low[u] = min(low[u],dfn[v]);
49     }
50 }
51 int main()
52 {
53     int cas = 1;
54     int flag,u,v;
55     while(scanf("%d",&u)&&u)
56     {
57         Init();
58         scanf("%d",&v);
59         if(u > nodes) nodes = u;
60         if(v > nodes) nodes = v;
61         InsertEdge(u,v);
62         InsertEdge(v,u);
63         while(scanf("%d",&u)&&u)
64         {
65             scanf("%d",&v);
66             if(u > nodes) nodes = u;
67             if(v > nodes) nodes = v;
68             InsertEdge(u,v);
69             InsertEdge(v,u);
70         }
71         Trajan(1);
72         if(son > 1) subnets[1] = son-1;
73         if(cas > 1) printf("\n");
74         printf("Network #%d\n",cas++);
75         flag = 0;
76         for(int i=1; i<=nodes; i++)
77         {
78             if(subnets[i])
79             {
80                 flag = 1;
81                 printf("  SPF node %d leaves %d subnets\n",i,subnets[i]+1);
82             }
83         }
84         if(!flag) printf("  No SPF nodes\n");
85     }
86     return 0;
87 }
View Code

邻接矩阵版本

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 #define N 1005
 8 int Edge[N][N];
 9 int dfn[N];
10 int low[N];
11 int nodes;
12 int index;
13 int son;
14 int subnets[N];
15 
16 void Trajan(int u)
17 {
18     low[u] = dfn[u] = ++index;
19     for(int v=1; v<=nodes; v++)
20     {
21         if(Edge[u][v])
22         {
23             if(!dfn[v])
24             {
25                 Trajan(v);
26                 low[u] = min(low[u],low[v]);
27                 if(low[v] >= dfn[u])
28                 {
29                     if(u != 1) subnets[u]++;
30                     if(u == 1) son++;
31                 } 
32             }
33             else low[u] = min(low[u],dfn[v]);
34         }
35     }
36 }
37 
38 void Init()
39 {
40     nodes = son = 0;
41     index = 0;
42     memset(subnets,0,sizeof(subnets));
43     memset(dfn,0,sizeof(dfn));
44     memset(low,0,sizeof(low));
45     memset(Edge,0,sizeof(Edge));
46 }
47 
48 int main()
49 {
50     int flag,u,v;
51     int cas = 1;
52     while(scanf("%d",&u)&&u)
53     {
54         Init();
55         scanf("%d",&v);
56         if(u > nodes) nodes = u;
57         if(v > nodes) nodes = v;
58         Edge[u][v] = Edge[v][u] = 1;
59         while(scanf("%d",&u)&&u)
60         {
61             
62             scanf("%d",&v);
63             if(u > nodes) nodes = u;
64             if(v > nodes) nodes = v;
65             Edge[u][v] = Edge[v][u] = 1;
66         }
67         Trajan(1);
68         if(cas > 1) printf("\n");
69         if(son > 1) subnets[1] = son - 1 ;
70         printf("Network #%d\n",cas++);
71         flag = 0;
72         for(int i=1; i<=nodes; i++)
73         {
74             if(subnets[i])
75             {
76                 flag = 1;
77                 printf("  SPF node %d leaves %d subnets\n",i,subnets[i]+1);
78             }
79         }
80         if(!flag) printf("  No SPF nodes\n");
81     }
82     return 0;
83 }
View Code

 

posted on 2013-08-19 13:54  爱∪  阅读(150)  评论(0编辑  收藏  举报

导航