poj 3177 Redundant Paths(Tarjan,边双连通分量)

kuangbin模板中的例题,我把模板里的InStack去掉了。
思路:
poj 3177 Redundant Paths(Tarjan,边双连通分量)_第1张图片


#include 
#include 
#include 
using namespace std;

const int MAXN = 5010;
const int MAXM = 20010;
struct Edge
{
    int to,next;
    bool cut;
} edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],Dfn[MAXN],Stack[MAXN],Belong[MAXN];
int Index,top;
int block;
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(head,-1,sizeof(head));
    tot = 0;
}

void Tarjan(int u, int pre)
{
    int v;
    Low[u] = Dfn[u] = ++Index;
    Stack[top++] = u;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        v = edge[i].to;
        if(v == pre) continue;
        if(!Dfn[v])
        {
            Tarjan(v,u);
            if(Low[u] > Low[v]) Low[u] = Low[v];
            if(Low[v] > Dfn[u])
            {
                bridge++;
                edge[i].cut = true;
                edge[i^1].cut = true;
            }
        }
        else if(Low[u] > Dfn[v])
            Low[u] = Dfn[v];
    }
    if(Low[u] == Dfn[u])
    {
        block++;
        do
        {
            v = Stack[--top];
            Belong[v] = block;
        }while(v != u);
    }
}

int du[MAXN];
void solve(int n)
{
    memset(Dfn,0,sizeof(Dfn));
    Index = top = block = 0;
    Tarjan(1,0);
    int ans = 0;
    memset(du,0,sizeof(du));
    for(int i = 1; i <= n; ++i)
    {
        for(int j = head[i]; j != -1; j = edge[j].next)
        {
            if(edge[j].cut)
                du[Belong[i]]++;
        }
    }
    for(int i = 1; i <= block; ++i)
        if(du[i] == 1)
            ++ans;
    printf("%d\n",(ans+1)/2);
}

int main()
{
    int n,m,u,v;
    while(scanf("%d %d",&n,&m) != EOF)
    {
        init();
        while(m--)
        {
            scanf("%d %d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }
        solve(n);
    }
    return 0;
}

你可能感兴趣的:(强连通分量/双连通分量)