POJ2378 BZOJ3391 網絡破壞 Tarjan割點

POJ2378/BZOJ3391 網絡破壞 : Tarjan割點+dfs

Description

約翰意識到貝茜建設網絡花費了他鉅額的經費,就把她解僱了.貝茜很憤怒,打算狠狠報
復.她打算破壞剛建成的約翰的網絡. 約翰的網絡是樹形的,連接着N(1≤N≤10000)個牛棚.她打算切斷某一個牛棚的電源,使和這個牛棚相連的所有電纜全部中斷.之後,就會存在若干子網絡.爲保證破壞夠大,每一個子網的牛棚數不得超過總牛棚數的一半,那哪些牛棚值得破壞呢?

Input

第1行:一個整數N.
第2到N+1行:每行輸入兩個整數,表示一條電纜的兩個端點.

Output

按從小到大的順序,輸出所有值得破壞的牛棚.如果沒有一個值得破壞,就輸出“NONE”.

Sample Input
10
1 2
2 3
3 4
4 5
6 7
7 8
8 9
9 10
3 8
Sample Output
3
8
HINT

題解

這道題的技巧在於求一個割點分開的連通塊的大小。
一個割點將搜索樹中其子樹的點每個子樹一個連通塊,和這個點上面的點這幾個連通塊。我們在求出割點的時候判斷一下這個點是否值得割。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <algorithm>
#include <cstring>
#include <climits>
#define MAXN 10000+10
#define MAXM 10000+10
using namespace std;

int head[MAXN],num,n,m;
int dfn[MAXN],low[MAXN],vis[MAXN],dfnum,root,son;
int ans[MAXN],cnt[MAXN];
stack<int> st;
struct Edge{
    int from,to,next;
}edge[MAXN<<1];
void add(int from,int to)
{
    edge[++num].next=head[from];
    edge[num].from=from;
    edge[num].to=to;
    head[from]=num;
}
void tarjan(int x,int fa)
{   
    int flag=1,tmp=0;
    dfn[x]=low[x]=++dfnum;
    vis[x]=1;
    for(int i=head[x];i;i=edge[i].next)
    {   
        if(edge[i].to==fa) continue;
        if(!dfn[edge[i].to])
        {
            tarjan(edge[i].to,x);
            low[x]=min(low[x],low[edge[i].to]);
            vis[x]+=vis[edge[i].to];
            if(dfn[x]<=low[edge[i].to])
            {
                if(vis[edge[i].to]>n/2) flag=0;
                tmp+=vis[edge[i].to];
            }
        }else 
            if(vis[edge[i].to]) 
                low[x]=min(low[x],dfn[edge[i].to]);
    }
    if(n-1-tmp>n/2) flag=0;
    if(flag==1) 
    {
        if(!cnt[x]) cnt[0]++,cnt[x]=1;
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n-1;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    tarjan(1,0);
    if(cnt[0]==0) {printf("NONE\n");return 0;}
    for(int i=1;i<=n;i++)
    {   
        if(cnt[i]==1) printf("%d\n",i);
    }
    return 0;
}
發佈了50 篇原創文章 · 獲贊 4 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章