[无向图割点] PKU 1523 SPF

targan算法。

 1 # include <cstdio>
 2 # include <cstring>
 3 
 4 # define N (1000 + 5)
 5 
 6 int n, son, tmpdfn;
 7 int low[N], dfn[N], subnets[N];
 8 char g[N][N];
 9 
10 int Min(int x, int y)
11 {
12     return x<y ? x:y;
13 }
14 
15 void tarjan(int u, int r)
16 {
17     dfn[u] = low[u] = ++tmpdfn;
18     for (int v = 1; v <= n; ++v) if (g[u][v])
19     {
20         if (!dfn[v])
21         {
22             //dfn[v] = low[v] = ++tmpdfn;  // 时间戳打在这里就忽略了节点r,原图可能是不联通的(这道题是联通的)
23             tarjan(v, r);
24             low[u] = Min(low[u], low[v]);
25             if (low[v] >= dfn[u])
26             {
27                 if (u != r) ++subnets[u];
28                 else ++son;
29             }
30         }
31         else
32             low[u] = Min(low[u], dfn[v]);
33     }
34 }
35 
36 void init(void)
37 {
38     tmpdfn = 0;
39     memset(low+1, 0, sizeof(int)*n);
40     memset(dfn+1, 0, sizeof(int)*n);
41     memset(subnets+1, 0, sizeof(int)*n);
42 }
43 
44 void solve(void)
45 {
46     bool find = false;
47     for (int i = 1; i <= n; ++i) if (!dfn[i])
48     {
49         son = 0;
50         tarjan(i, i);
51         if (son > 1) subnets[i] = son - 1;
52     }
53     for (int i = 1; i <= n; ++i)
54     {
55         if (subnets[i])
56         {
57             find = true;
58             printf("\n  SPF node %d leaves %d subnets", i, subnets[i]+1);
59         }
60     }
61     if (find == false)
62         printf("\n  No SPF nodes");
63 }
64 
65 int read_graph(void)
66 {
67     n = 0;
68     memset(g, 0, sizeof(g));
69     int x, y;
70     scanf("%d", &x);
71     if (x == 0) return 0;
72     do
73     {
74         scanf("%d", &y);
75         g[x][y] = g[y][x] = 1;
76         if (x > n) n = x;
77         if (y > n) n = y;
78     }while (scanf("%d", &x), x);    
79     return 1;
80 }
81 
82 int main()
83 {    
84     int icase = 0;
85     while (read_graph())
86     {
87         if (icase != 0) printf("\n\n");
88         printf("Network #%d", ++icase);
89         init();
90         solve();
91     }
92 }

注意n=1的情况。

转载于:https://www.cnblogs.com/JMDWQ/archive/2012/08/07/2626705.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值