1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; const int M = 1e8; int vis[N]; int ctp[N]; stack<int> s; vector<int> rod[N]; int dfn[N], dc = 1; int low[N]; int cut[N]; vector<int> scc[N]; int sc = 1; void dfs(int u, int r) { s.push(u); cut[u]=(u==r)?0:1; low[u] = dfn[u] = dc++; if (u == r && rod[u].empty()) { int now = s.top(); s.pop(); scc[sc].push_back(now); sc++; } for (int j = 0; j < rod[u].size(); j++) { int to = rod[u][j]; if (!dfn[to]) { dfs(to, r); low[u] = min(low[u], low[to]); if (low[to] >= dfn[u]) { int now; do { now = s.top(); s.pop(); scc[sc].push_back(now); } while (now != to); scc[sc].push_back(u); sc++; cut[u]++; } } else { low[u] = min(low[u], dfn[to]); } } }
int main() { int n, m, a, b,cc=1; while (cin >> m&&m) { int mx=0; dc=1,sc=1; for (int i = 1; i <= m; i++) { scanf("%d%d", &a, &b); vis[a]=1,vis[b]=1; mx=max(mx,a); mx=max(mx,b); rod[a].push_back(b); rod[b].push_back(a); } int mn=0; ll cmn=1; for (int i = 1; i <= mx; i++) { if (vis[i]&&!dfn[i]) { dfs(i, i); } } for(int i=1;i<sc;i++) { int cnt=0; if(scc[i].size()==1) { mn++; } else { for(int j=0;j<scc[i].size();j++) { if(cut[scc[i][j]]>=2)cnt++; } if(cnt==0) { mn+=2; cmn*=(1ll*scc[i].size()-1)*1ll*scc[i].size()/2; } else if(cnt==1) { mn++; cmn*=1ll*(scc[i].size()-1); } } scc[i].clear(); } for(int i=1;i<=mx;i++) { if(vis[i]) { vis[i]=0; ctp[i]=0; rod[i].clear(); dfn[i]=low[i]=0; } } printf("Case %d: %d %lld\n",cc++,mn,cmn); } return 0; }
|