码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 2815 灭绝树

时间:2015-02-28 18:18:15      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

 

对于一个食物网(一个DAG),一个物种死亡后,某些物种就必然死亡,求出必然死亡的是那些物种。

 

灭绝树的另一种含义是:“灭绝树跟节点到节点u的路径上的节点由那些原图中从根节点到节点u的所有路径中都经过了的点“。

 

技术分享
  1 /**************************************************************
  2     Problem: 2815
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:424 ms
  7     Memory:14036 kb
  8 ****************************************************************/
  9 
 10 #include <cstdio>
 11 #include <vector>
 12 #define maxn 65544
 13 #define maxp 17
 14 using namespace std;
 15 
 16 int n;
 17 vector<int> g[maxn], vg[maxn], gg[maxn];
 18 int indgr[maxn], topo[maxn], topo_cnt;
 19 int anc[maxn][maxp+1], depth[maxn];
 20 int siz[maxn];
 21 
 22 
 23 void make_topo() {
 24     vector<int> stk;
 25     for( int i=1; i<=n; i++ ) 
 26         if( indgr[i]==0 ) stk.push_back(i);
 27     while( !stk.empty() ) {
 28         int u = stk.back();
 29         topo[++topo_cnt] = u;
 30         stk.pop_back();
 31         for( int t=0; t<g[u].size(); t++ ) {
 32             int v = g[u][t];
 33             indgr[v]--;
 34             if( indgr[v]==0 ) stk.push_back(v);
 35         }
 36     }
 37 }
 38 
 39 int lca( int u, int v ) {
 40     if( depth[u]<depth[v] ) swap(u,v);
 41     int t = depth[u]-depth[v];
 42     for( int i=0; t; t>>=1,i++ ) 
 43         if( t&1 ) u=anc[u][i];
 44     if( u==v ) return u;
 45     for( int p=maxp; p>=0&&anc[u][0]!=anc[v][0]; p-- )
 46         if( anc[u][p]!=anc[v][p] ) u=anc[u][p], v=anc[v][p];
 47     return anc[u][0];
 48 }
 49 
 50 void dfs( int u ) {
 51     siz[u] = 1;
 52     for( int t=0; t<gg[u].size(); t++ ) {
 53         int v = gg[u][t];
 54         dfs(v);
 55         siz[u] += siz[v];
 56     }
 57 }
 58 
 59 void work() {
 60     make_topo();
 61     for( int i=1; i<=n; i++ ) {
 62         anc[i][0] = i;
 63         depth[i] = 1;
 64     }
 65     for( int i=1; i<=n; i++ ) {
 66         int u = topo[i];
 67         if( vg[u].size()==0 ) continue;
 68         int ca = vg[u][0];
 69         for( int t=1; t<vg[u].size(); t++ ) {
 70             int v = vg[u][t];
 71             ca = lca(ca,v);
 72         }
 73         gg[ca].push_back(u);
 74         anc[u][0] = ca;
 75         depth[u] = depth[ca]+1;
 76         for( int p=1; p<=maxp; p++ ) 
 77             anc[u][p] = anc[anc[u][p-1]][p-1];
 78     }
 79     dfs(n);
 80     for( int i=1; i<=n-1; i++ ) 
 81         printf( "%d\n", siz[i]-1 );
 82 }
 83 
 84 int main() {
 85     scanf( "%d", &n );
 86     for( int v=1,u; v<=n; v++ ) {
 87         while(1) {
 88             scanf( "%d", &u );
 89             if( u==0 ) break;
 90             g[u].push_back(v);
 91             vg[v].push_back(u);
 92             indgr[v]++;
 93         }
 94     }
 95     for( int u=1; u<=n; u++ ) 
 96         if( indgr[u]==0 ) {
 97             g[n+1].push_back(u);
 98             vg[u].push_back(n+1);
 99             indgr[u]++;
100         }
101     n++;
102     work();
103 }
View Code

 

bzoj 2815 灭绝树

标签:

原文地址:http://www.cnblogs.com/idy002/p/4305752.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!