Network(连通图割点)

Network

Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Submit Status Practice UVA
315

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 together two places and in each place the lines end in a telephone exchange. There is one telephone exchange in each place. From each place it is possible to reach through lines every other place, however it need not be a direct connection,
it can go through several exchanges. From time to time the power supply fails at a place and then the exchange does not operate. The officials from TLC realized that in such a case it can happen that besides the fact that the place with the failure is unreachable,
this can also cause that some other places cannot connect to each other. In such a case we will say the place (where the failure occured) is critical. Now the officials are trying to write a program for finding the number of all such critical places. Help
them.

Input

The input file consists of several blocks of lines. Each block describes one network. In the first line of each block there is the number of places N < 100. 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. These at most N lines completely describe the network, i.e., each direct connection of two places in the network is contained at
least in one row. All numbers in one line are separated by one space. Each block ends with a line containing just 0. The last block has only one line with N = 0.

Output

The output contains for each block except the last in the input file one line containing the number of critical places.

Sample Input

5
5 1 2 3 4
0
6
2 1 3
5 4 6 2
0
0

Sample Output

1
2

连通图割点裸题。。。

相关资料:

http://blog.csdn.net/u014665013/article/details/50009399

http://blog.csdn.net/u014665013/article/details/51351810

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MOD 100000
#define inf 1<<29
#define LL long long

using namespace std;
/*
*  求  无向图   的割点和桥
*  可以找出割点和桥,求删掉每个点后增加的连通块。
*  需要注意重边的处理,可以先用矩阵存,再转邻接表,或者进行判重
*/
const int MAXN = 10010;
const int MAXM = 2000010;
struct Edge
{
    int to,next;
    bool cut;//是否为桥的标记
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN];
int Index,top;
bool Instack[MAXN];
bool cut[MAXN];   ///记录是否是割点
int add_block[MAXN];//删除一个点(i)后增加的连通块
int bridge;

void addedge(int u,int v)
{
    edge[tot].to = v;edge[tot].next = head[u];edge[tot].cut = false;
    head[u] = tot++;
}

void init(){
    memset(DFN,0,sizeof(DFN));
    memset(Instack,false,sizeof(Instack));
    memset(add_block,0,sizeof(add_block));
    memset(cut,false,sizeof(cut));
    memset(head,-1,sizeof(head));
    Index = top = tot = 0;
    bridge = 0;
}
void Tarjan(int u,int pre)  ///pre是父节点,用来判断重边
{
   // cout<<u<<endl;
    int v;
    Low[u] = DFN[u] = ++Index;
    Stack[top++] = u;
    Instack[u] = true;
    int son = 0;
    int pre_cnt = 0;  ///处理重边 ,如果不需要可以去掉
    for(int i = head[u];i != -1;i = edge[i].next)
    {
     //   cout<<v<<"__"<<endl;
        v = edge[i].to;
        if(v == pre && pre_cnt == 0)
        {
            pre_cnt++;
            continue;
        }
        if( !DFN[v] )
        {
            son++;
            Tarjan(v,u);
            if(Low[u] > Low[v])
                Low[u] = Low[v];
            ///桥
            ///一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足DFS(u)<Low(v)。
            if(Low[v] > DFN[u])
            {
                bridge++;
                edge[i].cut = true;
                edge[i^1].cut = true;
            }
            //割点
            //一个顶点u是割点,当且仅当满足(1)或(2)
            //(1) u为树根,且u有多于一个子树。
            //(2) u不为树根,且满足存在(u,v)为树枝边(或称父子边,即u为v在搜索树中的父亲),使得DFS(u)<=Low(v)
            if(u != pre && Low[v] >= DFN[u])//不是树根
            {
                cut[u] = true;
                add_block[u]++;
            }
        }
        else if( Low[u] > DFN[v])
             Low[u] = DFN[v];
    }
    //树根,分支数大于1
    if(u == pre && son > 1)
        cut[u] = true;
    if(u == pre)
       add_block[u] = son - 1;
    Instack[u] = false;
    top--;
}
void solve(int n){
    Tarjan (1, 1);
   // cout<<"++++++++++\n";
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        if (cut[i])
        {
            ans++;
        }
    }
    printf("%d\n", ans);
}
int main()
{
    int n;
    int u, v;
    while (~scanf("%d", &n), n)
    {
        init();
        while (scanf("%d", &u), u)
        {
            while(getchar() != '\n')
            {
                scanf("%d", &v);
                addedge (u, v);
                addedge (v, u);
            }
        }
       // cout<<"=========\n";
        solve(n);
    }
    return 0;
}
时间: 2025-01-03 00:43:47

Network(连通图割点)的相关文章

UVA315 Network 连通图割点

题目大意:有向图求割点 题目思路: 一个点u为割点时当且仅当满足两个两个条件之一: 1.该点为根节点且至少有两个子节点 2.u不为树根,且满足存在(u,v)为树枝边(或称 父子边,即u为v在搜索树中的父亲),使得 dfn(u)<=low(v). 然后注意读入,很容易RE #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<vector&

【连通图|割点】POJ-1144 Network

Network Time Limit: 1000MS Memory Limit: 10000K 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 li

TOJ 2018 SPF(连通图割点和分成的连通块)

描述 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 availabl

Poj 3694 Network (连通图缩点+LCA+并查集)

题目链接: Poj 3694 Network 题目描述: 给出一个无向连通图,加入一系列边指定的后,问还剩下多少个桥? 解题思路: 先求出图的双连通分支,然后缩点重新建图,加入一个指定的边后,求出这条边两个端点根节点的LCA,统计其中的桥,然后把这个环中的节点加到一个集合中,根节点标记为LCA. 题目不难,坑在了数组初始化和大小 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #inclu

【POJ1144】Network(割点)(模板)

题意:给定一张无向图,求割点个数 思路:感谢CC大神http://ccenjoyyourlife.blog.163.com/的讲解 割点的定义就是某个联通块中删去此点连通性发生变化的的点 有两种割点:1.U为树根,子树个数>1 2.U非树根,有U的子节点V满足low[v]>=dfn[u]表示U的V子树必须通过U去到U的上面 更新时也有两种:dfn[u]<dfn[v]时u--->v 实边 反则u--->v 虚边 实边时low[u]=min(low[u],low[v]) 虚边lo

Uva 315 Network 判断割点

模板题,注意输出 #include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> #include <vector> #include <stack> using namespace std; typedef long long LL; const int N = 1e2+5; int head[N],tot,n; struct Edge{ i

求无向连通图的割点

求一个连通图的割点,割点的定义是,如果除去此节点和与其相关的边,图不再连通. 连通图的定义:如果图中任意两点都是连通的,那么图被称作连通图.如果此图是有向图,则称为强连通图(注意:需要双向都有路径) 割点:在无向连通图中,删除一个顶点v及其相连的边后,原图从一个连通分量变成了两个或多个连通分量,则称顶点v为割点,同时也称关节点 (Articulation Point).多连通图没有割点,若在多连通图上至少删去k个顶点才能破坏图的连通性,则称此图为k连通图.貌似有向连通图没有割点这个说法. 连通分

Tarjan 联通图 Kuangbin 带你飞 联通图题目及部分联通图题目

Tarjan算法就不说了 想学看这 https://www.byvoid.com/blog/scc-tarjan/ https://www.byvoid.com/blog/biconnect/ 下面是几份基本的模版 首先是无向图割点桥的代码 下面的代码是用于求割点数目的 其中add_block[u] = x  表示删除u点之后增加的联通块个数.注意是增加的联通块个数 const int MAXN = 1010; const int MAXM = 10010; const int INF = 0x

Tarjan算法各种&amp;RMQ&amp; POJ 3694

关于tarjan 的思想可以在网上搜到,具体我也不太清楚,应该说自己理解也不深,下面是做题经验得到的一些模板. 其中有很多转载,包括BYVoid等,感谢让我转...望各路大神愿谅 有向图求连通分量的一般方法: 1 void Tarjan(u) { 2 dfn[u]=low[u]=++index 3 stack.push(u) 4 for each (u, v) in E { 5 if (v is not visted) { 6 tarjan(v) 7 low[u] = min(low[u], l