HNOI2012 礦場搭建

2021-10-08 19:29:05 字數 1546 閱讀 2338

顯然需要求一下點雙

然後列舉每乙個點雙,考慮進行分類討論

如果這乙個聯通塊裡面只有這乙個點雙,也就是這個點雙裡面沒有割點,那麼我們至少需要建造兩個出口,才能保證能跑出去(因為有可能選的那個塌了)

如果這個點雙裡面有乙個割點,那麼有兩種情況,一種是割點塌了,這樣我們需要選出1個點,或者割點沒塌,這樣我們就可以跑到另乙個點雙裡面去了,這樣需要選出1個點

當這個點雙裡面有兩個割點,那麼我們最壞情況是乙個割點塌了,但是我們還是能跑到另乙個裡面。

這樣我們就可以解決了

#include

using

namespace std;

# define rep(i,a,b) for(int i=a;i<=b;i++)

# define _rep(i,a,b) for(int i=a;i>=b;i--)

# define repg(i,u) for(int i=head[u];~i;i=e[i].next)

typedef

long

long ll;

const

int n=

1005

;template

<

typename t>

void

read

(t &x)

int n,m;

int head[n]

,cnt;

int dfn[n]

,low[n]

,dfsxu;

int siz,sum,cutcnt,dcc;

int testcase;

bool cut[n]

;int vis[n]

;ll ans;

struct edgee[n<<1]

;void

add(

int x,

int y)

,head[x]

=cnt;

}void

tarjan

(int u,

int fa)

}else

if(v!=fa)low[u]

=min

(low[u]

,dfn[v]);

}if(cnt>=

2)cut[u]

=true;}

void

dfs(

int u)

dfs(v);}

}int

main()

rep(i,

1,n)if(

!dfn[i]

)tarjan

(i,i)

;rep

(i,1

,n)if

(!vis[i]

&&!cut[i]

)else

if(cutcnt==1)

}printf

("case %d: %d %lld\n"

,++testcase,sum,ans)

;read

(m);

}return0;

}

HNOI2012 礦場搭建

題目鏈結 演算法 對於任何乙個聯通塊,如果坍塌的是乙個聯通塊中的割點的話,那麼分割成的兩個小聯通塊中必須保證各有乙個出口。我們考慮所有的割點將原圖分割成若干個小聯通塊接下來分類討論 1 小塊不與任何乙個割點相連,那我們需要在這裡設立兩個出口,以保證任何乙個出口坍塌後,還有乙個出口可用。2 小塊只與乙...

HNOI2012 礦場搭建

其實是劉汝佳藍書上面的例題啦,wf2011的乙個題 首先我們可以發現,把割頂塗上是不優的。因為刪掉它之後,因此被和原圖斷掉的那一部分就沒有黑點了,它對不連通的分量產生不了任何貢獻。所以我們要先預處理出來點雙聯通分量的割頂,不塗割頂。其次,對於乙個雙聯通分量來講,我們到底要塗幾個呢?其實乙個就夠了,因...

HNOI2012 礦場搭建

煤礦工地可以看成是由隧道連線挖煤點組成的無向圖。為安全起見,希望在工地發生事故時所有挖煤點的工人都能有一條出路逃到救援出口處。於是礦主決定在某些挖煤點設立救援出口,使得無論哪乙個挖煤點坍塌之後,其他挖煤點的工人都有一條道路通向救援出口。請寫乙個程式,用來計算至少需要設定幾個救援出口,以及不同最少救援...