Dark的项链(树链剖分)
来源:互联网 发布:小学校园网络建设方案 编辑:程序博客网 时间:2024/04/29 13:03
P2272 - Dark的锁链
Description
无向图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark有N – 1条主要边,并且Dark的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark还有M条附加边。
你的任务是把Dark斩为不连通的两部分。一开始Dark的附加边都处于无敌状态,你只能选择一条主要边切断。一旦你切断了一条主要边,Dark就会进入防御模式,主要边会变为无敌的而附加边可以被切断。但是你的能力只能再切断Dark的一条附加边。现在你想要知道,一共有多少种方案可以击败Dark。注意,就算你第一步切断主要边之后就已经把Dark斩为两截,你也需要切断一条附加边才算击败了Dark。
Input
第一行包含两个整数N和M。
之后N – 1行,每行包括两个整数A和B,表示A和B之间有一条主要边。
之后M行以同样的格式给出附加边。
Output
输出一个整数表示答案。
Sample Input
4 1
1 2
2 3
1 4
3 4
Sample Output
3
Hint
对于20% 的数据,N≤100,M≤100。
对于100% 的数据,N≤100 000,M≤200 000。数据保证答案不超过2^31– 1。
Source
树链剖分, LCA
这个题是一个树剖的变形。
对于一个点
1.不被任何副边覆盖。answer+=m;
2.被一条副边覆盖。只能断掉主边,再断掉这条副边,answer++;
3.被多条副边覆盖。不能达到目的.
附:用线段树写可能超时,可以差分记录被覆盖数目。
注意!!!!!!!
*:在跳到同一条重链上时,差分(id[min(deep[x],deep[y])]+1,deep[max(deep[x],deep[y])])
(在最顶端时,非根节点有一条父边连向父亲,不要加);
*:最后统计差分数组时,应当跳过根节点:
#include<cstdlib>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#define MAXX 1000100using namespace std;struct data{ int nxt,to;}edge[MAXX*2];int top[MAXX],head[MAXX],hson[MAXX],siz[MAXX],id[MAXX],w[MAXX],fa[MAXX],deep[MAXX];int n,fr,to,tot,m,sm,ans;void add(int f,int t){edge[++tot].nxt=head[f],head[f]=tot;edge[tot].to=t;}void dfs1(int num,int f){ hson[num]=0;siz[num]=1;fa[num]=f;deep[num]=deep[f]+1; for(int i=head[num];i;i=edge[i].nxt)if(edge[i].to!=f){ int too=edge[i].to; dfs1(too,num); siz[num]+=siz[too]; if(siz[hson[num]]<siz[too])hson[num]=too; }}void dfs2(int num,int toop){ top[num]=toop,id[num]=++sm; if(hson[num])dfs2(hson[num],toop); for(int i=head[num];i;i=edge[i].nxt) if(edge[i].to!=hson[num]&&edge[i].to!=fa[num])dfs2(edge[i].to,edge[i].to);}void update(int x,int y){w[x]++,w[y+1]--;}void ask(int x,int y){ while(top[x]!=top[y]){ if(deep[top[x]]<deep[top[y]])swap(x,y); update(id[top[x]],id[x]); x=fa[top[x]]; } if(deep[x]>deep[y])swap(x,y); if(id[x]+1<=id[y])update(id[x]+1,id[y]);}int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<n;++i)scanf("%d%d",&fr,&to),add(fr,to),add(to,fr); dfs1(1,0),dfs2(1,1); for(int i=1;i<=m;++i)scanf("%d%d",&fr,&to),ask(fr,to); for(int i=2;i<=n;++i)w[i]+=w[i-1]; for(int i=2;i<=n;++i)if(!w[i])ans+=m;else if(!(w[i]-1))ans++; printf("%d",ans); return 0;}
- Dark的项链(树链剖分)
- DARK的锁链
- Eclipse 的 Dark 模板
- dARK
- dark
- VS2015 Blue和Dark的结合--Blue with Dark Editor
- 串起珍珠的项链
- HH的项链(diff)
- HH的项链
- -失而复得的项链-
- 坏掉的项链
- 【USACO】坏掉的项链
- [SDOI2009]HH的项链
- BZOJ1878 HH的项链
- 【Bzoj1878】HH的项链
- 【SDOI2009】HH的项链
- [P1203]坏掉的项链
- SDOI2009HH的项链
- play教程 第六课 play中的session
- 【初等概率论】 02
- 多图片上传预览
- Dos窗口下编译带中文的.java文件
- Android关于activity出现在最近任务列表的问题总结
- Dark的项链(树链剖分)
- Spring与Quartz的整合实现定时任务调度
- jdk安装和环境变量配置
- javascript 检测浏览器版本号
- AndroidStudio插件GsonFormat快速实现JavaBean
- OpenVPN的高级路由技术-内部路由
- 取消nginx对js css文件的缓存
- Material Design Palette 使用总结
- BlocksKit UIEditUserWordController causes A2DynamicDelegate UITextField+BlocksKit crash