POJ1523 SPF 【求割点Tarjan】

SPF

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6131   Accepted: 2814

Description

Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the still available nodes from
communicating with each other. Nodes 1 and 2 could still communicate with each other as could nodes 4 and 5, but communication between any other pairs of nodes would no longer be possible.

Node 3 is therefore a Single Point of Failure (SPF) for this network. Strictly, an SPF will be defined as any node that, if unavailable, would prevent at least one pair of available nodes from being able to communicate on what was previously a fully connected
network. Note that the network on the right has no such node; there is no SPF in the network. At least two machines must fail before there are any pairs of available nodes which cannot communicate.

Input

The input will contain the description of several networks. A network description will consist of pairs of integers, one pair per line, that identify connected nodes. Ordering of the pairs is irrelevant; 1 2 and 2 1 specify the same connection. All node numbers
will range from 1 to 1000. A line containing a single zero ends the list of connected nodes. An empty network description flags the end of the input. Blank lines in the input file should be ignored.

Output

For each network in the input, you will output its number in the file, followed by a list of any SPF nodes that exist.

The first network in the file should be identified as "Network #1", the second as "Network #2", etc. For each SPF node, output a line, formatted as shown in the examples below, that identifies the node and the number of fully connected subnets that remain when
that node fails. If the network has no SPF nodes, simply output the text "No SPF nodes" instead of a list of SPF nodes.

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

Greater New York 2000

题意:给定一张图,求出所有割点以及去掉割点将图分成的块数。

题解:用Tarjan求割点,对于每个当前点u,若它能连接到非父节点v点,则更新low[u],若dfn[u]<=low[v],且u点不为根节点,则u点即为割点,vertex[u]==u点的子树个数+1,若u点是根节点,则当且仅当u的子树个数>1时u点为割点,分割块数为其子树的个数。

#include <stdio.h>
#include <string.h>
#define maxn 1002
#define maxm maxn * maxn
/*
** vertex[i]用来存储若i为割点时能将图分割的块数
** sec是时间戳
** dfn[]存储到达节点的时间
** low[]存储节点i能到达的最早节点的时间
** sta[]存储点双连通分支
*/
int head[maxn], id, cas = 1, vertex[maxn], sec;
int dfn[maxn], low[maxn], n, sta[maxn], id2;
struct Node{
    int to, next;
} E[maxm];

int max(int a, int b){
    return a > b ? a : b;
}

int min(int a, int b){
    return a < b ? a : b;
}

void initial()
{
    id = n = id2 = sec = 0;
    memset(head, -1, sizeof(head));
    memset(vertex, 0, sizeof(vertex));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
}

void addEdge(int u, int v)
{
    E[id].to = v; E[id].next = head[u];
    head[u] = id++; E[id].to = u;
    E[id].next = head[v]; head[v] = id++;
}

void Tarjan(int pos, int father)
{
    dfn[pos] = low[pos] = ++sec;
    sta[id2++] = pos; int i;
    for(i = head[pos]; i != -1; i = E[i].next){
        if(E[i].to == father) continue; //过滤
        if(!dfn[E[i].to]){
            Tarjan(E[i].to, pos);
            low[pos] = min(low[pos], low[E[i].to]); //更新low
            if(dfn[pos] <= low[E[i].to]){
                while(sta[--id2] != E[i].to) ; //同一分支出栈
                ++vertex[pos]; //子树+1
            }
        }else low[pos] = min(low[pos], low[E[i].to]); //更新low
    }
}

void solve(int n)
{
    int i, u, v, ok = 0;
    Tarjan(1, 0); --vertex[1]; //根节点分支数要-1,输出时再+1
    printf("Network #%d\n", cas++);
    for(i = 1; i <= n; ++i){
        if(vertex[i] > 0){
            printf("  SPF node %d leaves %d subnets\n", i, vertex[i] + 1);
            ok = 1;
        }
    }
    if(ok == 0) printf("  No SPF nodes\n");
    printf("\n");
}

int main()
{
    //freopen("stdin.txt", "r", stdin);
    int u, v; initial();
    while(scanf("%d%d", &u, &v) != EOF){
        n = max(u, n);
        n = max(v, n);
        if(0 == u){
            solve(n); if(!v) break;
            initial(); scanf("%d", &u);
            n = max(u, n);
        }
        addEdge(u, v);
    }
    return 0;
}
时间: 2024-10-13 00:03:21

POJ1523 SPF 【求割点Tarjan】的相关文章

POJ 1523 SPF 求割点的好(板子)题!

题意: 给个无向图,问有多少个割点,对于每个割点求删除这个点之后会产生多少新的点双联通分量 题还是很果的 怎么求割点请参考tarjan无向图 关于能产生几个新的双联通分量,对于每个节点u来说,我们判断他是否是割点,即判断是否满足他的儿子v的low[v]>dfn[u] 而这个时候割掉这个点就会让双联通分量增加,所以搞一个数组记录一下这个操作的次数就行 请注意在是否是根节点的问题上特判 !!注意输出格式!! 1 #include<cstdio> 2 #include<algorithm

POJ1523 SPF【割点】【Tarjan】

题目链接: http://poj.org/problem?id=1523 题目大意: 有一个网络,在这个网络里,电脑之间的通信只能是两台电脑间(点对点)双向通信.如下面左图 所示:如果3号电脑出故障了,那么1号和2号之间.4号和5号之间还可以通信,不过1.2和3.4 号电脑之间就不能通信了,那么3号电脑就是一个SPF节点,且3号电脑故障后,整个网络被分为 了2个子网络.那么问题来了:给你一些边.问删除某个SPF节点后,可以将图分为几个连通分量. 思路: 其实就是给你一个连通图,求出这个连通图的所

POJ1523 SPF(割点)

题目求一个无向图的所有割点,并输出删除这些割点后形成几个连通分量.用Tarjan算法: 一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边). 顺便求出每个结点的DFS序dfn[u] 和 每个结点能沿着它和它的儿子的返祖边达到的结点最小的DFS序low[u]. 一个点是割点当且仅当—— 这个点是生成树的根,且有x(x>=2)个的子树,删除这个点后就形成x个连通分量. 这个点不是树根,且其存在x(x>=1)个儿子的low值小于等于该点的d

poj 1523 SPF 求割点以及删除该割点后联通块的数量

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7136   Accepted: 3255 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

poj1144Network 无向图求割点Tarjan

n个点,组成一个无向图,求这个图中割点的数量.模板题. 只是这道题在输入数据的时候有点麻烦,如样例中,第一组数据有五个点,5 1 2 3 4 表示5这个点与1 2 3 4 点相连.其中这个图的割点只是5这个点.第二组数据6个点,2 与1 3 5相连,5与2 4 6相连,其中2点与5点都是割点. 有两类节点可以成为割点: 对根节点u,若其有两棵或两棵以上的子树,则该根结点u为割点: 对非叶子节点u(非根节点),若其子树的节点均没有指向u的祖先节点的回边,说明删除u之后,根结点与u的子树的节点不再连

uva 315 Network(连通图求割点)

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=251  Network  A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers

POJ 1523 SPF 割点 Tarjan

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9317   Accepted: 4218 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

POJ 1523 SPF(强连通分量求割点)

题目地址:POJ 1523 这题猛的一看..貌似有点难的样子.不过仔细一想,那个每个割点所分成一次子图不就都能找到这个割点一次吗,那么只要记录下它作为割点的次数再+1不就行了.也算是求割点的裸题吧.这个题的输出很坑...需要注意一下.. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #incl

tarjan算法求割点cojs 8

tarjan求割点:cojs 8. 备用交换机 ★★   输入文件:gd.in   输出文件:gd.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] n个城市之间有通讯网络,每个城市都有通讯交换机,直接或间接与其它城市连接.因电子设备容易损坏,需给通讯点配备备用交换机.但备用交换机数量有限,不能全部配备,只能给部分重要城市配置.于是规定:如果某个城市由于交换机损坏,不仅本城市通讯中断,还造成其它城市通讯中断,则配备备用交换机.请你根据城市线路情况,计算需配备备用交换