「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 }