POJ3177 Redundant Paths【边双联通分量】【Tarjan】

题目链接:

http://poj.org/problem?id=3177


题目大意:

Bessie的农场有F块牧场,已知当前任意两个农场之间至少有一条路径相连(并不一定直接相连)

为了从某块牧场移动到另一块牧场,Bessie和她的伙伴经常需要经过腐烂的树林。奶牛们特别

反感经过不好走的路,于是Bessie决定在农场种再建几条路,使得在去某个地方时总能够有两

条完全独立的路可够选择。那么问题来了:F块牧场,R条路,问至少再修几条路就能使得农场

中任意两个牧场之间都有至少两条相互独立的路径。


思路:

为了使农场中任意两个牧场之间都有至少两条相互独立的路径。也就是把F块牧场看做点,R条

路看做是两个农场之间的双向边。那么问题就转换为:最少添加几条边,可以使图不存在割边。

也就是和POJ3352一样的问题:最少添加几条边,使得任意两个边连通分量之间相互双连通。

具体做法参考博文:http://blog.csdn.net/lianai911/article/details/43867789

注:此题比POJ3352多了一点,需要判重。。。所以我用了Map[][]数组。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 5050;
const int MAXM = 50500;

bool Map[MAXN][MAXN];
struct EdgeNode
{
    int to;
    int next;
}Edges[MAXM];
int Head[MAXN];
int dfn[MAXN],low[MAXN],Stack[MAXN],degree[MAXN];
int m,id,scc,lay,M,N;

void AddEdges(int u,int v)
{
    Edges[id].to = v;
    Edges[id].next = Head[u];
    Head[u] = id++;
}

void TarjanBFS(int pos,int from)
{
    //Stack[m++] = pos;
    dfn[pos] = low[pos] = ++lay;
    for(int i = Head[pos]; i != -1; i = Edges[i].next)
    {
        if(Edges[i].to == from)
            continue;
        if( !dfn[Edges[i].to] )
        {
            TarjanBFS(Edges[i].to,pos);
            low[pos] = min(low[pos],low[Edges[i].to]);
//            if( dfn[pos] < low[Edges[i].to] )
//            {
//                while(Stack[m--] != Edges[i].to);
//            }
        }
        else
            low[pos] = min(low[pos],low[Edges[i].to]);
    }
}

int main()
{
    int u,v;
    while(~scanf("%d%d",&N,&M))
    {
        memset(Head,-1,sizeof(Head));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(degree,0,sizeof(degree));
        m = lay = scc = id = 0;

        memset(Map,0,sizeof(Map));
        for(int i = 0; i < M; ++i)
        {
            scanf("%d%d",&u,&v);
            if(Map[u][v] == 0)
            {
                AddEdges(u,v);
                AddEdges(v,u);
                Map[u][v] = Map[v][u] = 1;
            }
          
            
        }
        TarjanBFS(1,-1);
        for(int i = 1; i <= N; ++i)
        {
            for(int j = Head[i]; j != -1; j = Edges[j].next)
            {
                if(low[i] != low[Edges[j].to])
                    degree[low[i]]++;
            }
        }

        int ans = 0;
        for(int i = 1; i <= N; ++i)
            if(degree[i] == 1)
                ans++;
        printf("%d\n",(ans+1)/2);
    }

    return 0;
}


你可能感兴趣的:(POJ3177 Redundant Paths【边双联通分量】【Tarjan】)