poj 1523 SPF 无向图求割点

SPF

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

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define mod 1000000007
#define inf 999999999
int scan()
{
    int res = 0 , ch ;
    while( !( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ ) )
    {
        if( ch == EOF )  return 1 << 30 ;
    }
    res = ch - ‘0‘ ;
    while( ( ch = getchar() ) >= ‘0‘ && ch <= ‘9‘ )
        res = res * 10 + ( ch - ‘0‘ ) ;
    return res ;
}
int dfn[1010];
int low[1010];
int head[1010];
int ans[1010];
int visit[1010];
int index,root,son,node,jiedge;
struct is
{
    int u,v;
    int next;
}edge[1010];
void add(int x,int y)
{
    jiedge++;
    edge[jiedge].u=x;
    edge[jiedge].v=y;
    edge[jiedge].next=head[x];
    head[x]=jiedge;
    jiedge++;
    edge[jiedge].u=y;
    edge[jiedge].v=x;
    edge[jiedge].next=head[y];
    head[y]=jiedge;
}
void dfs(int u)
{
    for(int i=head[u];i;i=edge[i].next)
    {
        int v=edge[i].v;
        if(visit[v]==0)
        {
            visit[v]=1;++index;
            dfn[v]=low[v]=index;
            dfs(v);
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u])
            {
                if(u==root)
                son++;
                else
                ans[u]++;
            }
        }
        else
        low[u]=min(low[u],dfn[v]);
    }
}
void trajan()
{
    memset(visit,0,sizeof(visit));
    memset(ans,0,sizeof(ans));
    index=1;
    root=1;
    son=0;
    low[1]=dfn[1]=1;
    visit[1]=1;
    dfs(1);
}
int main()
{
    int u,v;
    int flag=0;
    while(scanf("%d",&u)!=EOF)
    {
        memset(head,0,sizeof(head));
        jiedge=0;
        node=0;
        if(u==0)
        break;
        scanf("%d",&v);
        node=max(node,u);
        node=max(node,v);
        add(u,v);
        while(1)
        {
            scanf("%d",&u);
            if(u==0)
            break;
            scanf("%d",&v);
            add(u,v);
            node=max(node,u);
            node=max(node,v);
        }
        trajan();
        int kk=1;
        if(flag!=0)
            printf("\n");
        printf("Network #%d\n",++flag);
        if(son>1)
        {
            kk=0;
            printf("  SPF node %d leaves %d subnets\n",1,son);
        }
        for(int i=2;i<=node;i++)
        {
            if(ans[i])
            {
                kk=0;
                printf("  SPF node %d leaves %d subnets\n",i,ans[i]+1);
            }
        }
        if(kk)
        printf("  No SPF nodes\n");
    }
    return 0;
}

时间: 2024-08-10 17:21:31

poj 1523 SPF 无向图求割点的相关文章

poj 1144 Network 无向图求割点

Network Description A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N . No two places have the same number. The lines are bidirectional and always connect

POJ 1523 SPF(无向图割顶)

SPF 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 s

UVA 315 Network(无向图求割点)

题目大意 A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N. No two places have the same number. The lines are bidirectional and always connect together two pl

Poj 1144 Zoj 1311 求割点 模板

写这个就是为了手写一份好用的求割点模板: 吐槽下,题目中的 Each of the next at most N lines contains the number of a place followed by the numbers of some places to which there is a direct line from this place.  这个at most是不可信的,应该是用大于n行的测试数据,因为这个我WA了... #include <cstdio> #includ

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

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

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

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

POJ 1523 SPF(割点)

大致题意: 给出一个连通的无向图,求哪些点是割点,对于每个割点,求出去掉这个点后连通分量的个数.如果没有割点的话输出" No SPF nodes". 思路: 求割点用tarjan即可,然后要求删除割点后连通分量的个数,每次找到割点,再在从割点dfs即可,也可以直接在tarjan算法中记录child个数.那么如果割点是根,那么答案就是child,不是根的割点答案是child+1 //188K 0MS C++ 2121B #include<cstdio> #include<

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 1144 无向图求割点

学长写的: #include<cstdio>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#include<cstring>#include<vector>using namespace std;#define maxn 10005int dfn[maxn];///代表最先遍历到这个点的时间int low[maxn];///这个点所