码迷,mamicode.com
首页 > 其他好文 > 详细

UVAlive5135 Mining Your Own Business(bcc)

时间:2015-12-17 16:09:43      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

 

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19845

 

【思路】

       点-双连通分量。

       求出bcc,对于每个bcc而言,最优的方案就是在每一个只有一个割点的bcc中安置一个逃生装置。

 

【代码】

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<stack>
 4 #include<vector>
 5 #include<iostream>
 6 #include<cstdlib>
 7 #define FOR(a,b,c) for(int a=(b);a<(c);a++)
 8 using namespace std;
 9 
10 typedef long long LL;
11 const int maxn = 100000+10;
12 
13 struct Edge{ int u,v;
14 };
15 
16 int pre[maxn],iscut[maxn],bccno[maxn],dfs_clock,bcc_cnt;
17 vector<int> G[maxn],bcc[maxn];
18 
19 stack<Edge> S;
20 
21 int dfs(int u,int fa) {
22     int lowu=pre[u]=++dfs_clock;
23     int ch=0;
24     for(int i=0;i<G[u].size();i++) {
25         int v=G[u][i];
26         Edge e=(Edge) {u,v};
27         if(!pre[v]) {
28             S.push(e);
29             ch++;
30             int lowv=dfs(v,u);
31             lowu=min(lowu,lowv);
32             if(lowv>=pre[u]) {
33                 iscut[u]=1;
34                 bcc_cnt++; bcc[bcc_cnt].clear();
35                 for(;;) {
36                     Edge x=S.top(); S.pop();
37                     if(bccno[x.u]!=bcc_cnt) bcc[bcc_cnt].push_back(x.u),bccno[x.u]=bcc_cnt;
38                     if(bccno[x.v]!=bcc_cnt) bcc[bcc_cnt].push_back(x.v),bccno[x.v]=bcc_cnt;
39                     if(x.u==u && x.v==v) break;
40                 }
41             }
42         }
43         else if(pre[v]<pre[u] && v!=fa) {
44             S.push(e);  lowu=min(lowu,pre[v]); 
45         }
46     }
47     if(fa<0 && ch==1) iscut[u]=0;
48     return lowu; 
49 }
50 void find_bcc(int n) {
51     memset(pre,0,sizeof(pre));
52     memset(iscut,0,sizeof(iscut));
53     memset(bccno,0,sizeof(bccno));
54     dfs_clock=bcc_cnt=0;
55     for(int i=0;i<n;i++)
56         if(!pre[i]) dfs(i,-1);
57 }
58 
59 int n,m,kase;
60 
61 int main() {
62     while(scanf("%d",&m) && m) {
63         int u,v;
64         n=0;
65         for(int i=0;i<2*m;i++) G[i].clear();
66         for(int i=0;i<m;i++) {
67             scanf("%d%d",&u,&v);
68             u--,v--;
69             n=max(n,max(u,v));
70             G[u].push_back(v);
71             G[v].push_back(u);
72         }
73         while(!S.empty()) S.pop();
74         
75         find_bcc(n);
76         
77         LL ans1=0,ans2=1;
78         for(int i=1;i<=bcc_cnt;i++) {
79             int cnt=0;
80             for(int j=0;j<bcc[i].size();j++)
81                 if(iscut[bcc[i][j]]) cnt++;
82             if(cnt==1) {
83                 ans1++; ans2*=(long long)(bcc[i].size()-1);
84             }
85         }
86         if(bcc_cnt==1) {
87             ans1=2; ans2=bcc[1].size()*(bcc[1].size()-1)/2;
88         }
89         printf("Case %d: %lld %lld\n",++kase,ans1,ans2);
90     }
91     return 0;
92 }

 

UVAlive5135 Mining Your Own Business(bcc)

标签:

原文地址:http://www.cnblogs.com/lidaxin/p/5054148.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!