【POJ 3177】Redundant Paths(邊雙連通份量)

求出每一個邊雙連通份量縮點後的度,度爲1的點即葉子節點。原圖加上(leaf+1)/2條邊便可變成雙連通圖。ios

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>

using namespace std;
const int N = 5010;
const int M = 10010;
struct Edge
{
    int to,next;
    bool cut;
}edge[M];
int head[N],tot;
int Low[N],DFN[N],Stack[N],Belong[N];
int Index,top;
int block;
bool Instack[N];
int bridge;
void addedge(int u,int v)
{
    edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
    edge[tot].cut=false;
}
void Tarjan(int u,int pre)
{
    int v;
    Low[u] = DFN[u] = ++Index;
    Stack[top++] = u;
    Instack[u] = true;
    for(int i = head[u];~i;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(Instack[v] && Low[u] > DFN[v])
            Low[u] = DFN[v];
    }
    if(Low[u] == DFN[u])
    {
                block++;
                do
                {
                        v = Stack[--top];
                        Instack[v] = false;
                        Belong[v] = block;
                }
                while( v != u);
    }
}
int du[N];//縮點後造成樹,每一個點的度數
void solve(int n)
{
        memset(DFN,0,sizeof(DFN));
        memset(Instack,false,sizeof Instack);
        Index = block = top = 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;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);
}
void init()
{
        tot = 0;
        memset(head,-1,sizeof head);
}
int main()
{
    int n,m;
    int u,v;
    while(scanf("%d%d",&n,&m)==2)
    {
        init();
        while(m--)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }
        solve(n);
    }
    return 0;
}

 

  

┆涼┆暖┆降┆等┆幸┆我┆我┆裏┆將┆ ┆可┆有┆謙┆戮┆那┆ ┆大┆始┆ ┆然┆ ┆薄┆一┆臨┆你┆的┆還┆沒┆ ┆來┆ ┆是┆來┆遜┆沒┆些┆ ┆雁┆終┆ ┆而┆ ┆ ┆暖┆ ┆如┆地┆站┆有┆ ┆也┆ ┆我┆ ┆的┆有┆精┆ ┆也┆沒┆ ┆你┆ ┆ ┆這┆ ┆試┆方┆在┆逃┆ ┆會┆ ┆在┆ ┆清┆來┆準┆ ┆沒┆有┆ ┆沒┆ ┆ ┆生┆ ┆探┆ ┆最┆避┆ ┆在┆ ┆這┆ ┆晨┆ ┆的┆ ┆有┆來┆ ┆有┆ ┆ ┆之┆ ┆般┆ ┆不┆ ┆ ┆這┆ ┆裏┆ ┆沒┆ ┆殺┆ ┆來┆ ┆ ┆來┆
相關文章
相關標籤/搜索