[ZJOI2012] 灾难
https://hydro.ac/d/bzoj/p/2815
Solution
如果 $x$ 能供给 $y$,则连 $(x,y)$。
我们想要把它变成一个支配树的形式,新建图连向深度最深的且支配它一个点。比如 $(1,2),(1,3),(2,4),(3,4)$。则有 $(1,2),(1,3),(1,4)$。
在拓扑排序的过程中,观察到如果一个点它的入边的父亲都确定了,则这个点的父亲就是他们的 lca。
动态加边做 lca,倍增即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define maxn 100005 #define put() putchar('\n') #define Tp template<typename Ty> #define Ts template<typename Ty,typename... Ar> using namespace std; void read(int &x){ int f=1;x=0;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} x*=f; } namespace Debug{ Tp void _debug(char* f,Ty t){cerr<<f<<'='<<t<<endl;} Ts void _debug(char* f,Ty x,Ar... y){while(*f!=',') cerr<<*f++;cerr<<'='<<x<<",";_debug(f+1,y...);} Tp ostream& operator<<(ostream& os,vector<Ty>& V){os<<"[";for(auto& vv:V) os<<vv<<",";os<<"]";return os;} #define gdb(...) _debug((char*)#__VA_ARGS__,__VA_ARGS__) }using namespace Debug; #define fi first #define se second #define mk make_pair const int mod=1e9+7; int power(int x,int y=mod-2) { int sum=1; while (y) { if (y&1) sum=sum*x%mod; x=x*x%mod;y>>=1; } return sum; } vector<int>to[maxn],O[maxn],e[maxn]; int fa[maxn][21]; int n,m,lg[maxn],in[maxn],deep[maxn]; int query(int x,int y) { if (deep[x]<deep[y]) swap(x,y); while (deep[x]>deep[y]) x=fa[x][lg[deep[x]-deep[y]]]; if (x==y) return x; for (int i=lg[deep[x]];i>=0;i--) if (fa[x][i]^fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } queue<int>q; int siz[maxn]; void dfs(int x) { siz[x]=1; for (auto y:O[x]) dfs(y),siz[x]+=siz[y]; } signed main(void){ int i,x; read(n); for (i=2;i<=n;i++) lg[i]=lg[i/2]+1; for (i=1;i<=n;i++) { read(x); while (x) { to[x].push_back(i); e[i].push_back(x); in[i]++; read(x); } } for (i=1;i<=n;i++) if (!in[i]) q.push(i),deep[i]=1; while (!q.empty()) { x=q.front();q.pop(); int tmp=-1; for (auto y:e[x]) { if (tmp==-1) tmp=y; else tmp=query(tmp,y); } tmp=max(tmp,0); fa[x][0]=tmp;deep[x]=deep[tmp]+1; O[tmp].push_back(x); for (i=1;i<=lg[deep[x]];i++) fa[x][i]=fa[fa[x][i-1]][i-1]; for (auto y:to[x]) if (!--in[y]) q.push(y); } dfs(0); for (i=1;i<=n;i++) printf("%d\n",siz[i]-1); return 0; }
|