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. WinForm DataGridView增删改查

    DataGridView连接数据库对表进行增删改查 一.绑定数据源 //做一个变量控制页面刷新 ; public Form1() { InitializeComponent(); } private ...

  2. gevent调度流程解析

    gevent是目前应用非常广泛的网络库,高效的轮询IO库libev加上协程(coroutine),使得gevent的性能非常出色,尤其是在web应用中.本文介绍gevent的调度流程,主要包括geve ...

  3. EF6多线程与分库架构设计之Repository

    1.项目背景 这里简单介绍一下项目需求背景,之前公司的项目基于EF++Repository+UnitOfWork的框架设计的,其中涉及到的技术有RabbitMq消息队列,Autofac依赖注入等常用的 ...

  4. java异常的一些小知识

    异常,我们软件都需要面对的一个问题.如何让你的软件更加健壮呢?这是一个值得我们考虑的问题.这里主要为大家介绍一下异常是什么,异常是如何产生的,如何将异常抛出,如何捕获异常,对于异常应该如何处理的个人一 ...

  5. Swift 2.2 协议和代理

    一:代理 两个类之间的传值,类A调用类B的方法,类B在执行过程中遇到问题通知类A,这时候我们需要用到代理(Delegate). 比如:控制器(Controller)与控制器(Controller)之间 ...

  6. 搭建Eclipse开发和调试环境(真机)

    由于工作原因,最近开始了Android开发.之前接触过一段时间Android,还是在2.x时代. 那个时候搭建开发环境还是挺麻烦的.又是Eclipse,又是ADT的,不同的版本还要安装对应开发包.现在 ...

  7. JUnit与JMock学习

    JUnit与JMock学习 测试驱动编程和持续集成部署应该说是现在软件开发者的必备武器,不过跟其他很多好东西一样,在我们公司的推广总要慢上一拍,毕竟老板看的是你能够把功能实现好让客户满意,所以能不折腾 ...

  8. 浅谈css中一个元素如何在其父元素居中显示

    css如何垂直居中一个元素的问题已经是一个老生常谈的问题了.不管对于一个新手或者老手,在面试过程中是经常被问到的.前两天在看一个flex的视频教程,当中提到了有关元素的居中问题,所以今天小编就来扒一扒 ...

  9. android学习19--Matrix.mapPoints作用

    android图形的旋转,缩放,平移都是用matrix实现的.可以用mapPoints来计算一个点旋转,缩放,平移后的坐标.看下面例子. Matrix matrix = new Matrix(); m ...

  10. PAT---完美数列

    由于数值比较大,选用long型的 先用快速排序方法对数组进行排序,然后进行查找. 用一个问题是所要查找的数可能不在数组中,因此不能用现成的二叉查找法.试着对二叉查找法进行改进,单没调通. 在查找过程中 ...