POJ 3352 Road Construction

要使游客不受道路施工的影响,能够到达各个景点,那么就要使图是至少一个双连通分量,因为

施工时只对一道路施工。

这样模型就建立了: 给定一个连通的无向图G,至少要添加几条边,才能使其变为双连通图。

同样用tarjan缩点,然后求出缩点树的叶子结点个数,再按照公式计算。

/*Accepted    220K    0MS    C++    1783B    2012-07-30 09:53:31*/

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<algorithm>

using namespace std;



const int MAXN = 1 << 10;

const int MAXR = 1 << 11;

int low[MAXN], first[MAXN], next[MAXR], v[MAXR], s[MAXN], color[MAXN];

int dfn[MAXN], N, R, e, top, cnt, col, dgr[MAXN], ans;



void addedge(int x, int y)

{

    v[e] = y;

    next[e] = first[x], first[x] = e ++;

}



void tarjan(int cur, int p)

{

    int i;

    low[cur] = dfn[cur] = ++ cnt;

    s[top ++] = cur;

    for(i = first[cur]; i != -1; i = next[i])

    {

        if(v[i] != p)

        {

            if(!dfn[v[i]])

            {

                tarjan(v[i], cur);

                if(low[v[i]] < low[cur])

                    low[cur] = low[v[i]];

            }

            else if(dfn[v[i]] < low[cur])

                low[cur] = dfn[v[i]];

        }

    }

    if(low[cur] == dfn[cur])

    {

        ++ col;

        for(s[top] = -1; s[top] != cur; )

            color[s[-- top]] = col;

    }

}



void cal()

{

    int i, j, k;

    ans = 0;

    col = cnt = top = 0;

    memset(dfn, 0, sizeof dfn);

    tarjan(1, -1);

    memset(dgr, 0, sizeof dgr);

    for(i = 1; i <= N; i ++)

        for(j = first[i]; j != -1; j = next[j])

            if(color[i] != color[v[j]])

                ++ dgr[color[i]], ++ dgr[color[v[j]]];

    for(i = 1; i <= col; i ++)

        if(dgr[i] == 2)

            ++ ans;

    ans = (ans + 1) / 2;

}



void ReadGraph()

{

    int i, x, y;

    memset(first, -1, sizeof first);

    e = 0;

    for(i = 0; i < R; i ++)

    {

        scanf("%d%d", &x, &y);

        addedge(x, y), addedge(y, x);

    }

}



int main()

{

    while(scanf("%d%d", &N, &R) == 2)

    {

        ReadGraph();

        cal();

        printf("%d\n", ans);

    }

}

 

你可能感兴趣的:(struct)