P3225 [HNOI2012]矿场搭建

  1 #include<iostream>
  2 #include<string>
  3 #include<queue>
  4 #include<stack>
  5 #include<vector>
  6 #include<map>
  7 #include<cstdio>
  8 #include<cstdlib>
  9 #include<algorithm>
 10 #include<set>
 11 #include<list>
 12 #include<iomanip>
 13 #include<cstring>
 14 #include<cmath>
 15 #include<limits>
 16 using namespace std;
 17 
 18 #define au auto
 19 #define debug(i) cout<<"<debug> "<<i<<"<\debug>"<<endl
 20 #define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
 21 #define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
 22 #define LLL __int128
 23 #define Re register
 24 #define il inline
 25 #define mem(a,b) memset(a,(b),sizeof(a))
 26 typedef pair<int, int> intpair;
 27 typedef long long int LL;
 28 const int INF = 0x3f3f3f3f;
 29 const long long int INFLL = 0x3f3f3f3f3f3f3f3f;
 30 
 31 int cnt;
 32 const int maxn = 501;
 33 int n;
 34 
 35 struct Edge
 36 {
 37     int u, nxt;
 38 }e[maxn << 2];
 39 
 40 int head[maxn];
 41 
 42 void add(int a, int b)
 43 {
 44     e[++cnt].u = b;
 45     e[cnt].nxt = head[a];
 46     head[a] = cnt;
 47 }
 48 
 49 int dfn[maxn];
 50 int low[maxn];
 51 bool cut[maxn];
 52 int gro[maxn];
 53 int tot;
 54 int tott;
 55 LL ans[2];
 56 int root;
 57 int cntf;
 58 int cntn;
 59 int cntc;
 60 int Case;
 61 
 62 void dfs(int x)
 63 {
 64     gro[x] = tot;
 65     cntn++;
 66     for (Re int i = head[x]; i != -1; i = e[i].nxt)
 67     {
 68         int u = e[i].u;
 69         if (cut[u] && gro[u] != tot) 
 70         {
 71             cntc++;
 72             gro[u] = tot;
 73         }
 74         if (!gro[u]) dfs(u);
 75     }
 76 }
 77 
 78 void tarjan(int x, int fa)
 79 {
 80     dfn[x] = low[x] = ++tott;
 81     for (Re int i = head[x]; i != -1; i = e[i].nxt)
 82     {
 83         int u = e[i].u;
 84         if (!dfn[u])
 85         {
 86             tarjan(u, x);
 87             low[x] = min(low[x], low[u]);
 88             if (low[u] >= dfn[x])
 89             {
 90                 if (x != root) cut[x] = true;
 91                 else cntf++;
 92             }
 93         }
 94         else if (u != fa) low[x] = min(low[x], dfn[u]);
 95     }
 96 }
 97 
 98 int m;
 99 
100 int main()
101 {
102     while (cin >> n)
103     {
104         if (!n) break;
105         mem(head, -1);
106         mem(dfn, 0);
107         mem(low, 0);
108         mem(gro, 0);
109         mem(e, 0);
110         mem(cut, false);
111         ans[0] = 0;
112         ans[1] = 1;
113         cnt = 0;
114         tot = 0;
115         tott = 0;
116         m = 0;
117         mfor(i, 1, n)
118         {
119             int a, b;
120             cin >> a >> b;
121             add(a, b);
122             add(b, a);
123             m = max(m, max(a, b));
124         }
125         mfor(i, 1, m)
126         {
127             if (!dfn[i])
128             {
129                 root = i;
130                 cntf = 0;
131                 tarjan(i, i);
132                 if (cntf >= 2) cut[i] = true;
133             }
134         }
135         mfor(i, 1, m)
136         {
137             if (!gro[i] && !cut[i])
138             {
139                 tot++;
140                 cntn = cntc = 0;
141                 dfs(i);
142                 if (!cntc)
143                 {
144                     ans[0] += 2;
145                     ans[1] *= (LL)cntn * (cntn - 1LL) >> 1;
146                 }
147                 else if (cntc == 1)
148                 {
149                     ans[0]++;
150                     ans[1] *= cntn;
151                 }
152             }
153         }
154         cout << "Case " << ++Case << ": " << ans[0] << " " << ans[1] << endl;
155     }
156     return 0;
157 }
View Code

 

posted on 2019-10-20 21:03  thjkhdf12  阅读(105)  评论(0)    收藏  举报