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

bzoj2815 ZJOI2012 灾难

时间:2016-02-29 16:35:49      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

先求拓扑序

现在要求一棵树,如果某一个结点消失,那么整棵子树都会消失

一个点能影响的只能是在拓扑序中比它靠前的,于是边往树中加点,就边求一个点在原图中连接的点的lca

为了保证这些点能受到当前要加入点的影响,就按拓扑序加点,最后dfs一遍找出子树大小

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 void inin(int &ret)
 27 {
 28     ret=0;int f=0;char ch=getchar();
 29     while(ch<0||ch>9){if(ch==-)f=1;ch=getchar();}
 30     while(ch>=0&&ch<=9)ret*=10,ret+=ch-0,ch=getchar();
 31     ret=f?-ret:ret;
 32 }
 33 int sta[100010],top,n,m;
 34 struct wocao
 35 {
 36     int head[100010],next[100020],zhi[100020],in[100010],ed,s[100010],fa[100010][20],shen[100010];
 37     int st[100010],to;
 38     void add(int a,int b)
 39     {
 40         next[++ed]=head[a],head[a]=ed,zhi[ed]=b;
 41         in[b]++;
 42     }
 43     void dfs(int x)
 44     {
 45         s[x]=1;
 46         for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x][0])
 47         {
 48             fa[zhi[i]][0]=x;
 49             dfs(zhi[i]);
 50             s[x]+=s[zhi[i]];
 51         }
 52     }
 53     int lca(int a,int b)
 54     {
 55         if(a==-1)return b;
 56         if(shen[a]<shen[b])swap(a,b);
 57         int temp=shen[a]-shen[b];
 58         rre(i,19,0)if(temp&(1<<i))a=fa[a][i];
 59         rre(i,19,0)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
 60         return a==b?a:fa[a][0];
 61     }
 62     void topsort()
 63     {
 64         re(i,1,n)if(!in[i])st[++to]=i;
 65         while(to)
 66         {
 67             int x=st[to--];
 68             sta[++top]=x;
 69             for(int i=head[x];i;i=next[i])
 70             {
 71                 in[zhi[i]]--;
 72                 if(!in[zhi[i]])st[++to]=zhi[i];
 73             }
 74         }
 75     }
 76     void nima(int x)
 77     {
 78         re(i,1,17)fa[x][i]=fa[fa[x][i-1]][i-1];
 79     }
 80 }A,B;
 81 void wori()
 82 {
 83     rre(i,top,1)
 84     {
 85         int temp=sta[i],f=-1;
 86         for(int i=A.head[temp];i;i=A.next[i])
 87             f=B.lca(f,A.zhi[i]);
 88         if(f==-1)f=0;
 89         B.add(f,temp);
 90         B.shen[temp]=B.shen[f]+1;
 91         B.fa[temp][0]=f;
 92         B.nima(temp);
 93     }
 94 }
 95 int main()
 96 {
 97     inin(n);
 98     re(i,1,n)
 99     {
100         int x;
101         while(1)
102         {
103             inin(x);
104             if(!x)break;
105             A.add(i,x);
106         }
107     }
108     A.topsort();
109     wori();
110     B.dfs(0);
111     re(i,1,n)printf("%d\n",B.s[i]-1);
112      return 0;
113 }

 

bzoj2815 ZJOI2012 灾难

标签:

原文地址:http://www.cnblogs.com/HugeGun/p/5227577.html

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