lightoj 1026 - Critical Links 【DFS求块 + 边双连通求桥】

原创 2015年11月18日 21:03:04

1026 - Critical Links
PDF (English) Statistics Forum
Time Limit: 2 second(s) Memory Limit: 32 MB

In a computer network a link L, which interconnects two servers, is considered critical if there are at least two servers A and B such that all network interconnection paths between A and B pass through L. Removing a critical link generates two disjoint sub-networks such that any two servers of a sub-network are interconnected. For example, the network shown in figure 1 has three critical links that are marked red: 0 - 13 - 4 and 6 - 7 in figure 2.

Figure 1: Original Graph

Figure 2: The Critical Links

It is known that:

1.      The connection links are bi-directional.

2.      A server is not directly connected to itself.

3.      Two servers are interconnected if they are directly connected or if they are interconnected with the same server.

4.      The network can have stand-alone sub-networks.

Write a program that finds all critical links of a given computer network.

Input

Input starts with an integer T (≤ 15), denoting the number of test cases.

Each case starts with a blank line. The next line will contain n (0 ≤ n ≤ 10000) denoting the number of nodes. Each of the next n lines will contain some integers in the following format:

u (k) v1 v2 ... vk

Where u is the node identifier, k is the number of adjacent nodes; v1, v2 ... vk are the adjacent nodes of u. You can assume that there are at most 100000 edges in total in a case. Dataset is huge, so use faster i/o methods.

Output

For each case, print the case number first. Then you should print the number of critical links and the critical links, one link per line, starting from the beginning of the line, as shown in the sample output below. The links are listed in ascending order according to their first element and then second element. Since the graph is bidirectional, print a link u v if u < v.

Sample Input

Output for Sample Input

3

 

8

0 (1) 1

1 (3) 2 0 3

2 (2) 1 3

3 (3) 1 2 4

4 (1) 3

7 (1) 6

6 (1) 7

5 (0)

 

0

 

2

0 (1) 1

1 (1) 0

Case 1:

3 critical links

0 - 1

3 - 4

6 - 7

Case 2:

0 critical links

Case 3:

1 critical links

0 - 1

Note

Dataset is huge, use faster I/O methods.


SPECIAL THANKS: JANE ALAM JAN (MODIFIED DESCRIPTION, DATASET)



题意:给定n个节点的无向图,让你求出所有的桥。注意,图不连通时求每个块的桥。


思路:DFS找到所有块,标记块里面的点。对当前块求桥。


AC代码:


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-4
#define MAXN (10000+10)
#define MAXM (1000000+100)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 100000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
using namespace std;
struct Edge{
    int from, to, next;
};
Edge edge[MAXM], num[MAXM];
int head[MAXN], edgenum;
bool cmp(Edge a, Edge b)
{
    if(a.from != b.from)
        return a.from < b.from;
    else
        return a.to < b.to;
}
int dfs_clock, bridge, n;
void init()
{
    CLR(head, -1);
    edgenum = 0;
}
void addEdge(int u, int v)
{
    Edge E = {u, v, head[u]};
    edge[edgenum] = E;
    head[u] = edgenum++;
}
void getMap()
{
    Ri(n); init();
    for(int i = 0; i < n; i++)
    {
        int a, b, k; Ri(a);
        scanf(" (%d)", &k);
        while(k--)
        {
            Ri(b);
            if(b > a)
            {
                addEdge(a, b);
                addEdge(b, a);
            }
        }
    }
}
stack<int> S;
bool Instack[MAXN];
int low[MAXN], dfn[MAXN];
bool used[MAXN], mark[MAXN];
void tarjan(int u, int fa)
{
    int v;
    low[u] = dfn[u] = ++dfs_clock;
    S.push(u); Instack[u] = true;
    int have = 1;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        v = edge[i].to;
        if(!mark[v]) continue;
        if(v == fa && have)
        {
            have = 0;
            continue;
        }
        if(!dfn[v])
        {
            tarjan(v, u);
            low[u] = min(low[u], low[v]);
            if(low[v] > dfn[u])
            {
                num[bridge].from = min(u, v);
                num[bridge++].to = max(u, v);
            }
        }
        else if(Instack[v])
            low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u])
    {
        for(;;)
        {
            v = S.top(); S.pop();
            Instack[v] = false;
            if(v == u) break;
        }
    }
}
void DFS(int u)
{
    used[u] = mark[u] = true;
    for(int i = head[u]; i != -1; i = edge[i].next)
        if(!mark[edge[i].to])
            DFS(edge[i].to);
}
void find_cut(int l, int r)
{
    CLR(low, 0); CLR(dfn, 0); CLR(Instack, false);
    dfs_clock = 0;
    for(int i = l; i <= r; i++)
        if(mark[i] && !dfn[i])
            tarjan(i, -1);
}
int kcase = 1;
void solve()
{
    CLR(used, false); bridge = 0;
    for(int i = 0; i < n; i++)
    {
        if(!used[i])
        {
            CLR(mark, false);
            DFS(i);
            find_cut(0, n-1);
        }
    }
    printf("Case %d:\n", kcase++);
    printf("%d critical links\n", bridge);
    sort(num, num+bridge, cmp);
    for(int i = 0; i < bridge; i++)
        printf("%d - %d\n", num[i].from, num[i].to);
}
int main()
{
    int t; Ri(t);
    W(t)
    {
        getMap();
        solve();
    }
    return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

LightOJ 1026 - Critical Links (tarjan 找桥)

题意:找出所有的桥,并输出。 水题,中午肚子痛,查不出错了,晚上一看,tarjan写错了!!!! #include #include #include #include #incl...

Light 1026 - Critical Links (边-双连通分量 + 缩点)

RT

uva796 Critical Links(求桥并按边输出)

思路:模板题...求桥并按边输出 #include #include #include #include #include #include #include #include #...

UVA796Critical Links(求桥)(tarjan模板题)

题目链接:UVA796Critical Links 给你一个无向图,让你把桥边输出 1.这图不一定连通。 2.边按字典序输出#include #include #include #include...

UVA 796 Critical Links(求桥)

求 无向图的割点和桥 可以找出割点和桥,求删掉每个点后增加的连通块。 需要注意重边的处理,可以先用矩阵存,再转邻接表,或者进行判重#include #include #include #inclu...

UVA796.Critical Links——无向图的桥

http://www.bnuoj.com/v3/problem_show.php?pid=17935题目描述: 给定一个无向图,并不一定是连通图,求所有的桥#include #include #in...

【 LightOJ - 1094】Farthest Nodes in a Tree(求树的直径)链式向前星 + DFS or BFS

题意:求一棵树的直径(两点间的最长距离) 解题思路:求一颗树的最长直径,就是从树上任意一点出发找到一条最长的路,再找一条除了这条路以外的次长路,加起来就是树上的最长路(自己画画就明白了),所以用两种...
  • qwe585p
  • qwe585p
  • 2015年08月14日 21:05
  • 684

基于DFS求无向图的割点及桥(割边)算法总结 POJ_1144题解

1.割点,桥(割边)定义: 若v2(v1的后继节点)有且仅有反向边最远连接到v1,那么删除v1后不连通,v1是割点。作为一种特殊情况,如果v2及其后代通过反向边只能连回v2自己,那么只要删除edge...
  • zl_130
  • zl_130
  • 2015年08月13日 16:43
  • 179

lightoj 1063 - Ant Hills(强连通求割点)

After many years of peace, an ant-war has broken out. In the days leading up to the outbreak of war,...

LightOJ - 1291 Real Life Traffic (tarjan算法求强连通分量)

该题意为问你最小让加几条边使得删除任何一条边所有的顶点任然连通。 如果是不含环的图,使得所有的顶点度大于或等于2删除任何一条边其他的顶点任然连通,那么该题即转化为求连通分量的问题, 求出连通分量之...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:lightoj 1026 - Critical Links 【DFS求块 + 边双连通求桥】
举报原因:
原因补充:

(最多只允许输入30个字)