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 1000100
using 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的项链(树链剖分)的更多相关文章

  1. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  2. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  3. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  4. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  5. 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)

    题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...

  6. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  7. bzoj2243树链剖分+染色段数

    终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...

  8. bzoj3631树链剖分

    虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...

  9. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

随机推荐

  1. 双显卡笔记本安装CUDA+theano、tensorflow环境

    原文出处:http://www.cnblogs.com/jacklu/p/6377820.html 个人知乎主页欢迎关注:https://www.zhihu.com/people/jack_lu,相信 ...

  2. 论SNAPSHOT包的危害性

    先介绍一下背景:我们应用是一个标准的spring+webx工程,博主在一次项目发布前为了再次测试一下自己的代码,将分支部署到日常环境中,但是项目启动的时候报错: 第一眼看到这个堆栈后有点懵逼 第一是上 ...

  3. iOS Storyboard适配问题

      通用的Storyboard 通用的stroyboard文件是通向自适应布局光明大道的第一步.在一个storyboard文件中适配iPad和iPhone的布局在iOS8中已不再是梦想.我们不必再为不 ...

  4. Top命名的一些简单用法

    1. Top命令的显示 top 2. 按(Shift + O)是为了选择列进行排序.例如:按a是为了通过PID进行排序.然后按任意键返回主窗口. 3. 显示特定用户的进程. top -u hadoop ...

  5. 读书笔记 effective c++ Item 17 使用单独语句将new出来的对象放入智能指针

    1. 可能会出现资源泄漏的一种用法 假设我们有一个获取进程优先权的函数,还有一个在动态分类的Widget对象上根据进程优先权进行一些操作的函数: int priority(); void proces ...

  6. java初级开发程序员(第六单元)

    1.for循环结构: 循环结构分为四个部分. >初始部分:设置循环的初始状态,如设置记录循环次数的变量i为0. >循环体:重复执行的代码,即输出“好好学习,天天向上!”. >迭代部分 ...

  7. Kafka 0.10.1.1 特点

    1.Consumer优化:心跳线程可作为后台线程,提交offset,剥离出poll函数 问题:0.10新设计的consumer是单线程的,提交offset是在poll中.本次的poll调用,提交上次p ...

  8. DevExpress 控件使用之GridControl基本属性设置

    DEV控件:gridControl常用属性设置     1.隐藏最上面的GroupPanel(实现方法两种)     ①代码实现:gridView1.OptionsView.ShowGroupPane ...

  9. WP8.1程序开发,可视树VisualTreeHelper类的使用

    对于可视树的使用,很久之前就接触了, 一方面当时知识太浅根本看不懂,就放下没看了: 另一方面,也没用到,就没往这方面努力研究学习: 现在好了,遇到问题了,正好涉及到VisualTreeHelper的使 ...

  10. windows下读取utf-8文件

    #include <stdio.h> #include <tchar.h> #include <memory> int main() { FILE* fp1 = f ...