电厂计划

题目描述】:

停电,漆黑的夜晚。

ACM + +是一家电力公司。该公司拥有数个发电厂,每一个供应一个小面积,这些发电厂给这个公司带来了很多的麻烦,在某些地区没有足够的电力,而在其他地区却有大量的盈余。

ACM ++因此决定将一些发电厂连接成一个网络。当然第一阶段,没有必要将所有的发电厂连接到一个网络,但另一方面,它必须在关键地方建立冗余连接,即网络不保证是连通的。现在提出了各种连接的计划,并已开始复杂的评估。

必须考虑的评估标准之一是创建的网络的可靠性。我们假设可以发生的最坏的事件是一个发电厂故障,这可能会导致网络分成几个部分。虽然每一部分都可以工作,但被分成的部分越多,麻烦可能性就越大。因此,我们必须找出所有方案中,某个电厂故障,会形成的最大块数。

【输入描述】:

输入由若干实例组成。

每个实例第一行都包含两个整数P和C(1 <= P = 10,000,C >= 0),中间用空格隔开。P是电厂的数量。电厂编号为0到P - 1之间的整数。C是边数。下面的C行,每一行包含两个整数0 < = P1,P2<P用一个空格隔开,这意味着电厂P1和P2连接。每个连接不会重复描述。输入终止的行包含两个零。

【输出描述】:

输出由若干行组成。输出的第i行对应于第i个输入实例。输出的每一行由一个整数组成,即通过在实例中删除一个连接点,最多可以使网络分成的最大块数。

【样例输入】:

3 3
0 1
0 2
2 1
4 2
0 1
2 3
3 1
1 0
0 0

【样例输出】:

1
2
2

【时间限制、数据范围及描述】:

时间:1s 空间:64M

1 <= P = 10,000

注意没有边的情况

 
标准tarjan求桥,割点,缩点
 
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 int n,m;
 7 struct ENode{
 8     int u;
 9     int v;
10     int w;
11     int next;
12 }edge[50005];
13 int p[10005],cnt;
14 void Add(int u, int v){
15     edge[++cnt].u=u; 
16     edge[cnt].v=v;
17     edge[cnt].next=p[u];
18     p[u]=cnt;
19 }
20 int dfn[50005],cTime,low[50005];
21 int cut[50005]; 
22 void Tarjan(int u, int fa ){
23     dfn[u]=low[u]=++cTime;        
24     for(int i=p[u];i;i=edge[i].next){    
25         int v=edge[i].v;
26         if(v == fa)continue;
27         if(!dfn[v]){
28             Tarjan(v,u);
29             low[u]=min(low[u],low[v]);     
30             if(low[v]>=dfn[u]){        
31                 cut[u]++;        
32             }
33         }
34         else     
35             low[u]=min(low[u],dfn[v]);
36     }
37 }
38 int main(){
39     int x,y;
40     while(1){
41         int c=0,ans=-1;
42         scanf("%d%d",&n,&m);
43         if(!n&&!m)break;
44         memset(edge,0,sizeof(edge));
45         memset(p,0,sizeof(p));
46         cnt=0;
47         memset(dfn,0,sizeof(dfn));
48         cTime=0;
49         memset(low,0,sizeof(low));
50         memset(cut,0,sizeof(cut));
51         for(int i=0;i<m;i++){
52             scanf("%d%d",&x,&y);
53             Add(x+1,y+1);
54             Add(y+1,x+1);    
55         }
56         for(int i=1;i<=n;i++)
57             if(!dfn[i]){
58                 c++;
59                 cut[i]=-1;
60                 Tarjan(i,-1);
61             }
62         for(int i=1;i<=n;i++)
63             if(cut[i]>ans)ans=cut[i];
64         printf("%d\n",ans+c);
65     }
66     return 0;
67 }

 

posted @ 2019-07-09 13:33  [jackeylove]  阅读(135)  评论(0编辑  收藏  举报