11.5 T1.attack(拓扑+lca)
来源:互联网 发布:linux 批量删除进程 编辑:程序博客网 时间:2024/06/05 18:47
分析:
如果整个图是一棵树,那么针对每个询问
必经路径就是k个点的lca到根节点的路径
实际上扩展成一个普通的图也是这样
听男生们在讨论的时候,说这道题和灾难那道题”一样“
我仔细一想,确实哎,
我们现在手上的图是一个DAG
首先我们把ta的拓扑序计算出来
之后构造一个“拓扑树”:
假设当前点是x,x的祖先一定都在拓扑树中了
我们要找到与原图中直接指向x的所有点在拓扑树中的lca,把x挂在lca下
(根节点到x的路径一定会经过lca)
处理询问的时候,我们只要在拓扑树上寻找这k个点的lca,输出lca到根节点的结点个数即可
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#include<cmath>using namespace std;const int INF=0x33333333;const int N=50005;struct node{ int x,y,nxt;};node way[N<<1],e[N<<1];int st[N],tot=0,n,m,q,ste[N],tet=0;int deep[N],pre[N][20],lg,f[N],cnt[N],Q[N],in[N],tou,wei;bool vis[N];void add(int u,int w) //用来top的 { tet++; e[tet].x=u;e[tet].y=w;e[tet].nxt=ste[u];ste[u]=tet;}void ad(int u,int w) //用来建树的 { tot++; way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;}int LCA(int u,int w){ if (deep[u]<deep[w]) swap(u,w); int d=deep[u]-deep[w]; if (d) for (int i=0;i<=lg&&d;i++,d>>=1) if (d&1) u=pre[u][i]; if (u==w) return u; for (int i=lg;i>=0;i--) if (pre[u][i]!=pre[w][i]) { u=pre[u][i]; w=pre[w][i]; } return pre[u][0];}void Top(){ tou=wei=0; for (int i=1;i<=n;i++) if (in[i]==0) Q[++wei]=i,in[i]=INF;; while (tou<wei) { int now=Q[++tou],lca; for (int i=ste[now];i;i=e[i].nxt) { in[e[i].y]--; if (in[e[i].y]==0) { Q[++wei]=e[i].y; in[e[i].y]=INF; } } }}void doit(){ memset(pre,0,sizeof(pre)); deep[1]=1; for (int j=2;j<=wei;j++) { int now=Q[j]; int lca=-1; for (int i=st[now];i;i=way[i].nxt) //原图中前驱的lca if (lca==-1) lca=way[i].y; else lca=LCA(lca,way[i].y); deep[now]=deep[lca]+1; pre[now][0]=lca; for (int i=1;i<=lg;i++) //一边添加,一边维护pre pre[now][i]=pre[pre[now][i-1]][i-1]; }}int main(){ //freopen("attack.in","r",stdin); //freopen("attack.out","w",stdout); memset(in,0,sizeof(in)); scanf("%d%d%d",&n,&m,&q); lg=log(n)/log(2)+1; for (int i=1;i<=m;i++) { int u,w; scanf("%d%d",&u,&w); add(u,w); ad(w,u); in[w]++; } Top(); doit(); for (int i=1;i<=q;i++) { int x,u,now; scanf("%d",&x); scanf("%d",&now); for (int j=2;j<=x;j++) { scanf("%d",&u); now=LCA(u,now); } printf("%d\n",deep[now]); } return 0;}
阅读全文
0 0
- 11.5 T1.attack(拓扑+lca)
- [BZOJ2815][ZJOI2012]灾难(拓扑排序+LCA)
- 拓扑排序 [NOIP2003]神经网络 T1
- bzoj 2815(LCA+拓扑排序)(灭绝树)
- bzoj2815 灾难 拓扑排序&lca
- Attack
- Attack
- [BZOJ 2815][ZJOI 2012] 灾难 LCA+拓扑排序(支配树)
- 【ZJOI2012】【BZOJ2815】灾难 (catas) {拓扑+倍增lca}
- [BZOJ2815][ZJOI2012]灾难 拓扑排序+lca
- T1
- T1
- t1
- t1
- t1
- t1
- t1
- T1
- 初识TypeScript
- 【boolan c++】面向对象的三大方式以及设计模式
- 函数高级使用
- Mybatis(高级映射,一对一)
- Ubuntu../libstdc++.so.6: version `CXXABI_1.3.9' not found解决方法
- 11.5 T1.attack(拓扑+lca)
- 我的Spring学习记录(五)
- 【bzoj2590】[Usaco2012 Feb]Cow Coupons
- 锋利的jQuery第二版
- Windows下TensorFlow-gpu版安装教程
- leetcode解题方案--027--Remove Element
- 2017年11月5日 CCS布局基础 自学
- Mybatis(一对多查询)
- python 模拟登录CSDN