POJ 1144 Network(割点)

题目传送门

题目中文翻译:

Description

电话线公司(TLC)正在建立一个新的电话电缆网络。 他们正在连接几个地方编号从1N的整数。 没有两个地方有相同的号码。 这些线路是双向的,并且总是将两个地方连接在一起,并且在每个地方线路在电话交换机中结束。 每个地方都有一个电话交换台。 从每个地方都有可能通过其他地方的线路到达,但它不一定是直接连接,它可以经过几次交换。 电源不时会在某个地方出现故障,然后交换机不运行。 TLC的官员意识到,在这种情况下,除了发生故障的地方无法到达的事实之外,还会导致其他地方无法连接。 在这种情况下,我们会说这个地方(发生故障的地方)至关重要。 现在这些官员正在设法编写一个程序来查找所有这些关键地点的数量。帮助他们。

Input

输入文件由几个线块组成。 每个块描述一个网络。 在每个街区的第一行中有N <100的地点数目。下一个最多N行中的每一行都包含一个地方的号码,后面跟着这个地方有一条直线的地方的号码。 这些最多N行完整地描述网络,即网络中两个地方的每个直接连接至少包含在一行中。 一行中的所有数字由一个空格分隔。 每个块以包含0的行结束。最后一个块仅具有一条N = 0的行;

 

Output

除输入文件中的最后一行外,输出包含一行,其中包含关键位置的数量。

Sample Input

5

5 1 2 3 4

0

6

2 1 3

5 4 6 2

0

0

Sample Output

1

2

Hint

您需要确定一行的末端。为了便于确定,每行结束前都没有额外的空白。

解题思路:

求割点模板.

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 int n,head[1005],tot,dfn[1005],low[1005],_tot,a,cut[1005];
 8 char k; 
 9 struct kkk {
10     int to,next;
11 }e[1005];
12 
13 inline void add(int x,int y) {
14     e[++tot].to = y;
15     e[tot].next = head[x];
16     head[x] = tot;
17 }
18 
19 inline void tarjan(int x) {
20     int flag = 0;
21     dfn[x] = low[x] = ++_tot;
22     for(int i = head[x];i != -1; i = e[i].next) {
23         int u = e[i].to;
24         if(!dfn[u]) {
25             tarjan(u);
26             low[x] = min(low[x],low[u]);
27             if(low[u] >= dfn[x]){
28                 flag++; 
29                 if(x != 1 || flag > 1) cut[x] = true;
30             }
31         }
32         else
33             low[x] = min(low[x],dfn[u]);
34     }
35 }
36 
37 inline void chushihua() {
38     memset(head,-1,sizeof(head));
39     memset(dfn,0,sizeof(dfn));
40     memset(low,0,sizeof(low));
41     memset(cut,false,sizeof(cut));
42     tot = _tot = 0;
43 }
44 
45 int main() {
46     while(scanf("%d",&n) == 1 && n) {
47         chushihua();
48         while(scanf("%d",&a) == 1 && a) {
49             int b;
50             while((k = getchar()) != '\n') {
51                 scanf("%d",&b);
52                 add(a,b);
53                 add(b,a);    
54             }
55         }
56         int ans = 0;
57         for(int i = 1;i <= n; i++)
58             if(!dfn[i]) 
59                 tarjan(i);
60         for(int i = 1;i <= n; i++)
61             if(cut[i])
62                 ans++;
63         printf("%d\n",ans);
64     }
65     return 0;
66 } 

 

转载于:https://www.cnblogs.com/lipeiyi520/p/11487497.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值