对于一个食物网(一个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 }
时间: 2024-10-09 06:35:07