LA 5135 Mining Your Own Business

  求出 bcc 后再……根据大白书上的思路即可。

  然后我用的是自定义的 stack 类模板:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 //#include<stack>
  5 #include<stdexcept>
  6 #include<algorithm>
  7 using namespace std;
  8 typedef long long LL;
  9 const int N = 50003;
 10 
 11 template <typename T, size_t SIZE = N>
 12 class stack {
 13     T *val;
 14     size_t tot;
 15     size_t limit;
 16 public:
 17     stack(size_t limit = SIZE): limit(limit) {
 18         val = (T*)malloc(sizeof(T) * limit);
 19         tot = 0;
 20     }
 21     stack(const stack<T> &s2): limit(s2.limit), tot(s2.tot) {
 22         val = (T*)malloc(sizeof(T) * limit);
 23         for(size_t i = 0; i < tot; ++i)
 24             val[i] = s2.val[i];
 25     }
 26     stack& operator = (const stack<T> &s2) {
 27         tot = s2.tot;
 28         limit = s2.limit;
 29         T *temp = (T*)malloc(sizeof(T) * s2.limit);
 30         for(size_t i = 0; i < s2.tot; ++i)
 31             temp[i] = s2.val[i];
 32         free(val);
 33         this->val = temp;
 34     }
 35     void push(const T &x) {
 36         if(tot == limit) {
 37             stack<T> temp(*this);
 38             free(val);
 39             val = (T*)malloc(sizeof(T) * (limit <<= 1));
 40             for(size_t i = 0; i < temp.tot; ++i)
 41                 val[i] = temp.val[i];
 42         }
 43         val[tot++] = x;
 44     }
 45     void pop() {
 46         if(tot == 0)    throw out_of_range("Stack less flow at Stack<T>::pop()");
 47         --tot;
 48     }
 49     T top() const {
 50         if(tot == 0)    throw out_of_range("Stack less flow at Stack<T>::top()");
 51         return val[tot - 1];
 52     }
 53     size_t size() const {   return tot;   }
 54     bool empty() const {    return tot == 0;    }
 55     void clear() {   tot = 0;   }
 56     ~stack() {  free(val);   }
 57 };
 58 
 59 
 60 struct Edge {
 61     int u,v;
 62     Edge(int u, int v): u(u), v(v) {}
 63 };
 64 
 65 vector<int> g[N], bcc[N];
 66 int pre[N], iscut[N], bccno[N], dfs_clock, bcc_cnt;
 67 stack<Edge, N> s;
 68 
 69 int dfs(int u, int fa) {
 70     int lowu = pre[u] = ++dfs_clock;
 71     int child = 0;
 72     for(int i = 0; i < g[u].size(); ++i) {
 73         int v = g[u][i];
 74         Edge e = Edge(u,v);
 75         if(!pre[v]) {
 76             s.push(e);
 77             ++child;
 78             int lowv = dfs(v,u);
 79             lowu = min(lowu, lowv);
 80             if(lowv >= pre[u]) {
 81                 iscut[u] = 1;
 82                 ++bcc_cnt;
 83                 bcc[bcc_cnt].clear();
 84                 while(1) {
 85                     Edge x = s.top();   s.pop();
 86                     if(bccno[x.u] != bcc_cnt) {
 87                         bccno[x.u] = bcc_cnt;
 88                         bcc[bcc_cnt].push_back(x.u);
 89                     }
 90                     if(bccno[x.v] != bcc_cnt) {
 91                         bccno[x.v] = bcc_cnt;
 92                         bcc[bcc_cnt].push_back(x.v);
 93                     }
 94                     if(x.u == u && x.v == v)    break;
 95                 }
 96             }
 97         }
 98         else if(pre[v] < pre[u] && v != fa) {
 99             lowu = min(lowu, pre[v]);
100             s.push(e);
101         }
102     }
103     if(fa < 0 && child == 1)    iscut[u] = 0;
104     return lowu;
105 }
106 
107 void find_bcc(int n) {
108     memset(pre, 0, sizeof pre);
109     memset(iscut, 0, sizeof iscut);
110     memset(bccno, 0, sizeof bccno);
111     dfs_clock = bcc_cnt = 0;
112     for(int i = 0; i < n; ++i)
113         if(!pre[i])   dfs(i, -1);
114 }
115 
116 int main() {
117     int n,x,y,Case = 0, maxn = 1;
118     while(~scanf("%d",&n),n) {
119         for(int i = 0; i <= maxn; ++i)
120             g[i].clear();
121         maxn = 1;
122         for(int i = 0; i < n; ++i) {
123             scanf("%d %d",&x,&y);
124             maxn = max(maxn, x);
125             maxn = max(maxn, y);
126             g[x].push_back(y);
127             g[y].push_back(x);
128         }
129         find_bcc(maxn + 1);
130         LL ans1 = 0, ans2 = 1;
131         for(int i = 1; i <= bcc_cnt; ++i) {
132             int cut = 0;
133             for(int j = 0; j < bcc[i].size(); ++j)
134                 if(iscut[bcc[i][j]])    ++cut;
135             if(cut == 1) {
136                 ++ans1;
137                 ans2 *= bcc[i].size() - cut;
138             }
139         }
140         if(bcc_cnt == 1) {
141             ans1 = 2;
142             ans2 = (LL)bcc[1].size() * (bcc[1].size() - 1) / 2;
143         }
144         printf("Case %d: %lld %lld\n",++Case, ans1, ans2);
145     }
146     return 0;
147 }

 

posted @ 2015-08-29 08:48  Newdawn_ALM  阅读(215)  评论(0编辑  收藏  举报