在大家都在努力的考試的最後半個小時裡,不會做考試題的我來水乙個題解。
煤礦工地可以看成是由隧道連線挖煤點組成的無向圖。為安全起見,希望在工地發生事故時所有挖煤點的工人都能有一條出路逃到救援出口處。於是礦主決定在某些挖煤點設立救援出口,使得無論哪乙個挖煤點坍塌之後,其他挖煤點的工人都有一條道路通向救援出口。
請寫乙個程式,用來計算至少需要設定幾個救援出口,以及不同最少救援出口的設定方案總數。
輸入格式:
輸入檔案有若干組資料,每組資料的第一行是乙個正整數 n(n<=500),表示工地的隧道數,接下來的 n 行每行是用空格隔開的兩個整數 s 和 t,表示挖 s 與挖煤點 t 由隧道直接連線。輸入資料以 0 結尾。
輸出格式:
輸入檔案中有多少組資料,輸出檔案 output.txt 中就有多少行。每行對應一組輸入資料的 結果。其中第 i 行以 case i: 開始(注意大小寫,case 與 i 之間有空格,i 與:之間無空格,: 之後有空格),其後是用空格隔開的兩個正整數,第乙個正整數表示對於第 i 組輸入資料至少需 要設定幾個救援出口,第二個正整數表示對於第 i 組輸入資料不同最少救援出口的設定方案總 數。輸入資料保證答案小於 2^64。輸出格式參照以下輸入輸出樣例。
輸入樣例#1:
91 3
4 1
3 5
1 2
2 6
1 5
6 3
1 6
3 2
61 2
1 3
2 4
2 5
3 6
3 7
0
輸出樣例#1:
case 1: 2 4case 2: 4 1
case 1 的四組解分別是(2,4),(3,4),(4,5),(4,6);
case 2 的一組解為(4,5,6,7)。
思路:我們需要先找出割點,然後是所有的雙連通分量,最後統計出每個雙連通分量裡的個點的個數分類討論。
若該連通分量裡有不少於兩個割點,則它是安全的,因為無論哪個割點炸了,裡面的點可以通過其他的沒炸的割點跑到其他的雙連通分量裡去。
若該連通分量裡只有乙個割點,那麼如果這個割點炸了,則裡面的點就不可能跑到其他的雙連通分量裡去了,所以要在這個割點裡建乙個出口。
若該連通分量裡乙個割點也沒有,說明它與外界完全不連通,這時如果只建乙個出口的話,那麼如果這個出口炸了就gg,所以還需要另乙個出口「以防萬一」(即建兩個出口)的!!
對於方案數的話,我們發現如果要建出口的話,該雙連通分量裡的任何乙個非割點的節點都是可以的,那麼就可以搞定了啊。
這其實是個數學題啊!!
放上**。
#include#include#include
#include
#include
#include
using
namespace
std;
const
int ma=501
;int
n,sum,root,num;
intdfn[ma],low[ma],sk[ma];
bool
cut[ma];
inttp,ti,cnt;
vector
q[ma],g[ma];
inline
intread()
void tar(int
x) while(sk[tp+1]!=j);
g[cnt].push_back(x);}}
else low[x]=min(low[x],dfn[j]);
}} void
mem()
intmain()
for(int i=1;i<=n;i++)
if(!dfn[i])
long
long ans1=0,ans2=1
;
for(int i=1;i<=cnt;i++)
else
if(tg==1
) }
printf(
"case %d:
",++num);
cout
<"
"}return0;
}
完成!!
謝謝。
洛谷P3225 HNOI2012 礦場搭建
題意 煤礦工地可以看成是由隧道連線挖煤點組成的無向圖。為安全起見,希望在工地發生事故時所有挖煤點的工人都能有一條出路逃到救援出口處。於是礦主決定在某些挖煤點設立救援出口,使得無論哪乙個挖煤點坍塌之後,其他挖煤點的工人都有一條道路通向救援出口。請寫乙個程式,用來計算至少需要設定幾個救援出口,以及不同最...
洛谷 P3225 HNOI2012 礦場搭建
邊數n 500的挖煤點,需要設定盡量少的逃生出口,使得某個煤礦倒塌後,其他挖煤點的工人仍然可以通過某條路徑到達逃生出口,並給出逃生出口最少設定數量與方案數 多組資料 倒塌一座後 這一點令人想到割點 割點的倒塌會增加連通塊數量,產生隔斷 所以本題中顯然割點是比較重要的一種分析。先用tarjan跑出割點...
洛谷 P3225 HNOI2012 礦場搭建
煤礦工地可以看成是由隧道連線挖煤點組成的無向圖。為安全起見,希望在工地發生事故時所有挖煤點的工人都能有一條出路逃到救援出口處。於是礦主決定在某些挖煤點設立救援出口,使得無論哪乙個挖煤點坍塌之後,其他挖煤點的工人都有一條道路通向救援出口。請寫乙個程式,用來計算至少需要設定幾個救援出口,以及不同最少救援...