「BZOJ2730」[HNOI2012]矿场搭建

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=510;
 5 int n,T,ans1,cnt,siz,dfn[N],low[N],timer;
 6 ll ans2;
 7 bool vis[N],iscut[N],viscut[N];
 8 struct Edge{
 9     int from,to;
10     Edge(int _from=0,int _to=0):from(_from),to(_to){}
11 }edge[N<<1];
12 vector<int>point[N];
13 int edge_tot;
14 void add_edge(int f,int t){
15     edge[edge_tot]=Edge(f,t);
16     point[f].push_back(edge_tot++);
17     return;
18 }
19 int ff[N];
20 void tarjan(int k,int fa){
21     ff[k]=fa;
22     int child=0;
23     dfn[k]=low[k]=++timer;
24     for(int i=point[k].size()-1;i>=0;i--){
25         Edge& e=edge[point[k][i]];
26         if(!dfn[e.to]){
27             child++;
28             tarjan(e.to,k);
29             low[k]=min(low[k],low[e.to]);
30             if(low[e.to]>=dfn[k]) iscut[k]=1;
31         }else if(dfn[e.to]<dfn[k]&&e.to!=fa) low[k]=min(dfn[e.to],low[k]);
32     }
33     if(!fa&&child==1) iscut[k]=0;
34     return;
35 }
36 void dfs(int k,int pre){
37     vis[k]=1,siz++;
38     for(int i=0;i<point[k].size();i++){
39         Edge& e=edge[point[k][i]];
40         if(iscut[e.to]&&!viscut[e.to]) viscut[e.to]=1,cnt++;
41         if(iscut[e.to]||pre==e.to||vis[e.to])continue;
42         dfs(e.to,k);
43     }
44     return;
45 }
46 void solve(){
47     int t1,t2,tot=0;
48     ans1=edge_tot=0,ans2=1,timer=0;
49     T++;
50     for(int i=1;i<=n;i++){scanf("%d%d",&t1,&t2);add_edge(t1,t2);add_edge(t2,t1);tot=max(tot,max(t1,t2));}
51     for(int i=1;i<=tot;i++) if(!dfn[i]) tarjan(i,0);
52     memset(vis,0,sizeof(vis));
53     for(int i=1;i<=tot;i++) if(!iscut[i]&&!vis[i]){
54         cnt=siz=0;
55         memset(viscut,0,sizeof(viscut));
56         dfs(i,0);
57         if(!cnt) ans1+=2,ans2*=siz*(siz-1)/2;
58         else if(cnt==1) ans1++,ans2*=siz;
59     }
60     printf("Case %d: %d %lld\n",T,ans1,ans2);
61     for(int i=1;i<=tot;i++) point[i].clear();
62     memset(iscut,0,sizeof(iscut));memset(dfn,0,sizeof(dfn));
63     memset(low,0,sizeof(low));
64     return;
65 }
66 int main(){
67     while(scanf("%d",&n)!=EOF){
68         if(!n) return 0;
69         solve();
70     }
71 }

 

posted @ 2018-03-08 13:24  Cupcake  阅读(116)  评论(0编辑  收藏  举报