POJ 3177 Tarjan e-DCC

Title

Portal POJ 1377 Redundant Paths

answer

Add the least number of edges to the graph so that the entire graph constitutes an edge bi-connected component.

T a r j a n Tarjan T A R & lt J A n- algorithm cutting edge,E - the DCC-E the DCCeD C C shrinks points to form a tree. Connecting edges to the end points of the path obviously has more influence points than connecting edges to the points in the path, which makes the answer better. The degree of consideration is1 11 , any pair of such pointsx, yx, yx,Even the edges of y will make the path(x, lca (x, y), (lca (x, y), y) (x,lca(x,y),(lca(x,y),y)(x,lca(x,and ) ,(lca(x,and ) ,The points in y ) satisfy at least one ring. Suppose the degree in the new graph is1 11 point iscnt cntc n t , the answer is⌈ cnt / 2 ⌉ \lceil cnt/2\rceilcnt/2

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 5005, maxm = 10005 * 2;
int N, M, num, dcc, bg[maxm], dfn[maxn], low[maxn], deg[maxn], dc[maxn];
int tot, head[maxn], to[maxm], nxt[maxm];

inline void add(int x, int y) {
    
     to[++tot] = y, nxt[tot] = head[x], head[x] = tot; }

void tarjan(int x, int in)
{
    
    
    dfn[x] = low[x] = ++num;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i];
        if (!dfn[y])
        {
    
    
            tarjan(y, i);
            low[x] = min(low[x], low[y]);
            if (low[y] > dfn[x])
                bg[i] = bg[i ^ 1] = 1;
        }
        else if (i != (in ^ 1))
            low[x] = min(low[x], dfn[y]);
    }
}

void dfs(int x, int c)
{
    
    
    dc[x] = c;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i];
        if (!dc[y] && !bg[i])
            dfs(y, c);
    }
}

int main()
{
    
    
    scanf("%d%d", &N, &M);
    tot = 1;
    for (int i = 1, x, y; i <= M; ++i)
        scanf("%d%d", &x, &y), add(x, y), add(y, x);
    for (int i = 1; i <= N; ++i)
        if (!dfn[i])
            tarjan(i, 0);
    for (int i = 1; i <= N; ++i)
        if (!dc[i])
            ++dcc, dfs(i, dcc);
    for (int i = 2; i <= tot; i += 2)
    {
    
    
        int x = dc[to[i]], y = dc[to[i ^ 1]];
        if (x != y)
            ++deg[x], ++deg[y];
    }
    int res = 0;
    for (int i = 1; i <= N; ++i)
        res += deg[i] == 1;
    printf("%d\n", (res + 1) >> 1);
    return 0;
}

Guess you like

Origin blog.csdn.net/neweryyy/article/details/114868461