[HNOI2012]矿场搭建
<body>
<center><h1>2730: [HNOI2012]矿场搭建</h1><span class="green">Time Limit: </span>10 Sec <span class="green">Memory Limit: </span>128 MB<br><span class="green">Submit: </span>3565 <span class="green">Solved: </span>1700<br>[<a href="submitpage.php?id=2730">Submit</a>][<a href="problemstatus.php?id=2730">Status</a>][<a href="bbs.php?id=2730">Discuss</a>]</center><h2>Description</h2><div class="content"><div style="margin: 0cm 45.3pt 0pt 15.55pt; line-height: 13.25pt" align="left"><span style="font-size: medium"><span style="color: black">煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故</span><span style="color: black">时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出</span><span style="color: black">口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。</span><span style="color: black">请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。</span></span></div></div><h2>Input</h2><div class="content"><p><span style="font-size: medium"><span style="color: black">输入文件有若干组数据,每组数据的第一行是一个正整数</span><span style="color: black"> N</span><span style="color: black">(</span><span style="color: black">N≤500</span><span style="color: black">),表示工地的隧道数,接下来的</span><span style="color: black"> N </span><span style="color: black">行每行是用空格隔开的两个整数</span><span style="color: black"> S </span><span style="color: black">和</span><span style="color: black"> T</span><span style="color: black">,表示挖</span></span><span style="font-size: medium"><span style="color: black"><span style="font: 7pt 'Times New Roman'"> </span></span><span style="color: black">S </span><span style="color: black">与挖煤点</span><span style="color: black"> T </span><span style="color: black">由隧道直接连接。输入数据以</span><span style="color: black"> 0 </span><span style="color: black">结尾。</span></span></p></div><h2>Output</h2><div class="content"><p><span style="font-size: medium"><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">输入文件中有多少组数据,输出文件</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> output.txt </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">中就有多少行。每行对应一组输入数据的</span><span style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">结果。其中第</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> i </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">行以</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> Case i: </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">开始(注意大小写,</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">Case </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">与</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> i </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">之间有空格,</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">i </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">与</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">:</span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">之间无空格,</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体">: </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> i </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">组输入数据至少需</span><span style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">要设置几个救援出口,第二个正整数表示对于第</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> i </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">组输入数据不同最少救援出口的设置方案总</span><span style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> </span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">数。输入数据保证答案小于</span><span lang="EN-US" style="color: black; font-family: "Times New Roman"; mso-bidi-font-size: 12.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体"> 2^64</span><span style="color: black; font-family: 宋体; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">。输出格式参照以下输入输出样例。</span></span></p></div><h2>Sample Input</h2>
<div class="content"><span class="sampledata">9 <br>
1 3<br>
4 1<br>
3 5<br>
1 2<br>
2 6<br>
1 5<br>
6 3<br>
1 6<br>
3 2<br>
6 <br>
1 2<br>
1 3<br>
2 4<br>
2 5<br>
3 6<br>
3 7<br>
0<br>
</span></div><h2>Sample Output</h2>
<div class="content"><span class="sampledata">Case 1: 2 4<br>
Case 2: 4 1<br>
</span></div><h2>HINT</h2>
<div class="content"><p></p><div style="margin: 0cm -1.1pt 0pt 15.55pt; line-height: 11.25pt" align="left"><span style="font-size: 10pt; color: black">Case 1 </span><span style="font-size: 10pt; color: black">的四组解分别是</span><span style="font-size: 10pt; color: black">(2,4),(3,4),(4,5),(4,6)</span><span style="font-size: 10pt; color: black">;</span></div><br>
<div style="margin: 0.75pt -1.1pt 0pt 15.55pt; line-height: 11.25pt" align="left"><span style="font-size: 10pt; color: black">Case 2 </span><span style="font-size: 10pt; color: black">的一组解为</span><span style="font-size: 10pt; color: black">(4,5,6,7)</span><span style="font-size: 10pt; color: black">。</span></div><p></p></div><h2>Source</h2>
<div class="content"><p><a href="problemset.php?search=day1">day1</a></p></div><center>[<a href="submitpage.php?id=2730">Submit</a>][<a href="problemstatus.php?id=2730">Status</a>][<a href="bbs.php?id=2730">Discuss</a>]</center><br>
<a href="./"><span class="red">HOME</span></a>
<a href="javascript:history.go(-1)"><span class="red">Back</span></a>
<hr>
</body>
题解
如果被禁的点是割点,那么无影响。
先求出整个图的割点,通过删去割点得到的连通图就是bcc了,对于单个bcc,如果有超过2个割点连接,那么能不设置出口,通过无论哪个割点被删除都能从另一个割点出去,如果只有一个割点,那么bcc中除了割点的点都能作为出口.然后乘法求方案数.
注意标记的更改。
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef unsigned long long ull;
using namespace std;
co int N=1e3+1;
int n,m,num,anscnt,data;
int v[N],w[N],dfn[N],low[N];
vector<int> e[N];
ull ans;
void tarjan(int x){
dfn[x]=low[x]=++num;
v[x]=1;
for(unsigned i=0;i<e[x].size();++i){
int y=e[x][i];
if(!v[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
if(dfn[x]<=low[y]) ++v[x];
}
else low[x]=min(low[x],dfn[y]);
}
if(x==1&&v[x]>2||x>1&&v[x]>1) v[x]=2; // cut vertice
else v[x]=1; // edit 1: must be set 1
}
void dfs(int x,int&flag,int&cnt){
v[x]=3;
++cnt;
for(unsigned i=0;i<e[x].size();++i){
int y=e[x][i];
if(v[y]==1) dfs(y,flag,cnt);
else if(v[y]==2&&w[y]!=num){
++flag;
w[y]=num;
}
}
}
void work(){
for(int i=0;i<N;++i) e[i].clear();
n=0,memset(v,-1,sizeof v);
for(int x,y;m--;){
read(x),read(y);
n=max(n,max(x,y));
v[x]=v[y]=0;
e[x].push_back(y),e[y].push_back(x);
}
num=0;
for(int i=1;i<=n;++i)
if(!v[i]) tarjan(i);
num=0,memset(w,0,sizeof w),anscnt=0,ans=1;
for(int i=1;i<=n;++i)if(v[i]==1){
++num;
int flag=0,cnt=0;
dfs(i,flag,cnt);
if(flag==1) ++anscnt,ans*=cnt;
}
if(!anscnt) anscnt=2,ans=n*(n-1)/2;
printf("Case %d: %d %lld\n",++data,anscnt,ans);
}
int main(){
while(read(m)) work();
return 0;
}
静渊以有谋,疏通而知事。