Network

Description

Yixght is a manager of the company called SzqNetwork(SN). Now she's very worried because she has just received a bad news which denotes that DxtNetwork(DN), the SN's business rival, intents to attack the network of SN. More unfortunately, the original network of SN is so weak that we can just treat it as a tree. Formally, there are N nodes in SN's network, N-1 bidirectional channels to connect the nodes, and there always exists a route from any node to another. In order to protect the network from the attack, Yixght builds _M_new bidirectional channels between some of the nodes.

As the DN's best hacker, you can exactly destory two channels, one in the original network and the other among the M new channels. Now your higher-up wants to know how many ways you can divide the network of SN into at least two parts.

Input

The first line of the input file contains two integers: N (1 ≤ N ≤ 100 000), M (1 ≤ M ≤ 100 000) — the number of the nodes and the number of the new channels.

Following N-1 lines represent the channels in the original network of SN, each pair (a,b) denote that there is a channel between node a and node b.

Following M lines represent the new channels in the network, each pair (a,b) denote that a new channel between node a and node b is added to the network of SN.

Output

Output a single integer — the number of ways to divide the network into at least two parts.

Sample Input

4 1

1 2

2 3

1 4

3 4

Sample Output

3

树上乱搞题

最开始看了没有思路,第二天再看还是没有思路GG... 自己想到的是统计自己子树中有多少条附加边的一端,但是没细想,感觉情况很多,不好讨论。

事实上我们考虑,每多加一条非树边,在不重的情况下,树上都会多出一个环。

考虑断掉某条树边:

1.它可能没进入环,这时很显然再随意断开一条非树边即可。对答案的贡献为m。

2.它进入了一个环,这时我们再断开环中的那条非树边,成为一种方案。

3.它进入了两个环,树上部分成为两部分,但因为这条边处于两个环中,所以还有两条非树边从上半部分连到下半部分,无法使图成为两块。

4.它进入了多条环时与进入了两个环时情况类似,无法使图成为两块。

那这时思路就很显然了,对于每条非树边,我们把环上的每条树边入环个数++,但是我们发现这样做的话时间复杂度比较高,因为这样做需要遍历路径上的每一条边。这时考虑能不能把边转移到点上来记录,巨佬这时很容易想到运用树上差分的思想来解决(我还是太菜了,完全没想到)。对于每条非树边\((u,v)\):

a[u]++;a[v]++;a[lca(u,v)]-=2;

最后对于每个点按照上面的方法处理即可。

注意:不需要考虑根节点

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
const int N=100010;
int n,m,x,y,cnt,ans;
int head[N],deep[N],f[N][20],a[N];
struct node{
int to,next;
}edge[2*N];
void add(int x,int y)
{
cnt++;
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt;
}
void init()
{
for(int i=1;i<=19;i++)
for(int j=1;j<=n;j++)
f[j][i]=f[f[j][i-1]][i-1];
}
void dfs(int k,int fa)
{
for(int i=head[k];i;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa) continue;
deep[v]=deep[k]+1;f[v][0]=k;
dfs(v,k);
}
}
int LCA(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
for(int i=19;i>=0;i--)
{
if(deep[f[x][i]]>=deep[y]) x=f[x][i];
}
if(x==y) return x;
for(int i=19;i>=0;i--)
{
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
}
return f[x][0];
}
void get(int k,int fa)
{
for(int i=head[k];i;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa) continue;
get(v,k);
a[k]+=a[v];
}
}
int main()
{
n=read();m=read();
for(int i=1;i<n;i++)
{
x=read();y=read();
add(x,y);add(y,x);
}
dfs(1,0);init();
for(int i=1;i<=m;i++)
{
x=read();y=read();
int lca=LCA(x,y);
a[x]++;a[y]++;a[lca]-=2;
}
get(1,0);
for(int i=2;i<=n;i++)
{
if(a[i]==0) ans+=m;
else if(a[i]==1) ans++;
}
cout<<ans;
}

[POJ3417]Network(LCA,树上差分)的更多相关文章

  1. poj3417 Network——LCA+树上差分

    题目:http://poj.org/problem?id=3417 根据一条边被几个环覆盖来判断能不能删.有几种情况等: 用树上差分,终点 s++,LCA s-=2,统计时计算子树s值的和即可: 用S ...

  2. [BZOJ3307]:雨天的尾巴(LCA+树上差分+权值线段树)

    题目传送门 题目描述: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式: 第一 ...

  3. [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

  4. bzoj4326 树链剖分 + 线段树 // 二分 lca + 树上差分

    https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题意:N个点的树上给M条树链,问去掉一条边的权值之后所有树链长度和的最大值最小是多少. 首先 ...

  5. 2018.08.22 codves2370 小机房的树(lca+树上差分)

    传送门 一道板子题. 直接树链剖分维护树上lca然后差分就行了. 代码: #include<bits/stdc++.h> #define N 50005 #define lc (p< ...

  6. 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家

    [题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...

  7. [JLOI2014] 松鼠的新家 (lca/树上差分)

    [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在 ...

  8. LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*

    LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...

  9. [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)

    题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...

  10. bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】

    这居然是我第一次写线段树合并--所以我居然在合并的时候加点结果WAWAWAMLEMLEMLE--!ro的时候居然直接指到la就行-- 树上差分,每个点建一棵动态开点线段树,然后统计答案的时候合并即可 ...

随机推荐

  1. 在centos上配置环境

    1.   安装wget [root@localhost ~]# yum -y install wget 2.   在oneinstack官网配置安装环境 wget http://mirrors.lin ...

  2. 利用python进行数据分析--pandas入门1

    随书练习,第五章  pandas入门1 # coding: utf-8 # In[1]: from pandas import Series, DataFrame # In[2]: import pa ...

  3. 深入理解JVM虚拟机1:JVM内存的结构与消失的永久代

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  4. 《SQL Server 2012 T-SQL基础》读书笔记 - 4.子查询

    Chapter 4 Subqueries 子查询分为:独立子查询(Self-Contained Subqueries)和相关子查询(Correlated Subqueries),独立子查询可以单独拿出 ...

  5. ceph-pve英语

    adapted accordingly并相应地调整 silosn. 筒仓:粮仓:贮仓(silo的复数) saturatevt. 浸透,使湿透:使饱和,使充满While one HDD might no ...

  6. MyBatis系列:一、入门

    MyBatis无需我介绍,本系列文章是纯干货,没有一点废话. 1.创建一个maven项目,引入mysql的驱动和mybatis的maven引用 <dependency> <group ...

  7. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_02 递归_2_练习_使用递归计算1-n之间的和

    输出6 1到100之间的和 求和的原理

  8. 测开之路九十六:css进阶之元素显示和可见性

    元素显示效果:display 块级元素,会导致换行:p.div.h...内联元素,不会导致换行:span.strong... 修改属性 让span标签换行 让指定div不换行 元素可见性:visibi ...

  9. prometheus linux系统告警规则 实例

    #prometheus linux系统告警规则 实例 #根据实际情况修改参数 #rules.linux.yml groups: - name: linux rules: - alert: Node-D ...

  10. json 格式

    Json格式规则:(Douglas Crockford提出的) 1) 并列的数据之间用逗号(“,”)分隔. 2) 映射用冒号(“:”)表示. 3) 并列数据的集合(数组)用方括号("[]&q ...