题目传送门

  题目大意:给出一棵树,再给出m条非树边,先割掉一条树边,再割掉一条非树边,问有几种割法,使图变成两部分。

  思路:每一条 非树边会和一部分的树边形成一个环,分三种情况:

    对于那些没有形成环的树边来说,割掉这条边,就已经使图分离,然后随便割一条非树边就可以了,所以这样的边每次答案加上m。

    对于那些只存在在一个环中的树边来说,割掉这条边,再割一条和他存在于同一个环中的那条非树边,也能合法,所以加一。

    对于存在于多个环中的树边,无论怎样,都无法合法。

    也就是此时我们将题目转化成了树上的覆盖问题,非树边的两个端点覆盖的树上简单路径就是一个环,我们用树上差分来解决这个问题,先处理出lca,f数组表示每个点和父节点所在的边的覆盖次数。

    对于每一条非树边,端点是u,v,则f[ u ]和 f [ v ]加一,而u和v的公共祖先是没有影响的,所以f[ lca (u,v) ]要减去2,抵消这个影响。每个节点除了要加上直接对这个点操作的值,还要加上来自子树是否有覆盖,所以dfs求得子树的大小,此时 f 数组则代表每个点的父边所覆盖的次数。

  

//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<queue>
#include<iostream>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int n,m;
const int maxn=;
struct edges{
int to ,Next;
}a[maxn<<];
int head[maxn],tot,fa[maxn][],deg[maxn];
ll f[maxn];
inline void init(){
CLR(head,-),tot=;
CLR(f,);
}
inline void addv(int u,int v){
a[++tot]={v,head[u]};
head[u]=tot;
}
inline void bfs(){
queue<int >q;
deg[]=;
fa[][]=;
q.push();
while(!q.empty()){
int tmp=q.front();
q.pop();
for(int i=;i<;i++)
{
fa[tmp][i]= fa[fa[tmp][i-]][i-];
}
for(int i=head[tmp];i!=-;i=a[i].Next)
{
int v=a[i].to;
if(v==fa[tmp][])continue;
deg[v]=deg[tmp]+;
fa[v][]=tmp;
q.push(v);
}
}
}
inline int lca(int u,int v){
if(deg[u] > deg[v])swap(u,v);
int hu=deg[u],hv=deg[v];
int tu=u,tv=v;
for(int det=hv-hu,i=;det;det>>=,i++)
if(det&)
tv=fa[tv][i];
if(tu==tv)return tu;
for(int i=;i>=;i--){
if(fa[tu][i]==fa[tv][i])
continue;
tu=fa[tu][i];
tv=fa[tv][i];
}
return fa[tu][]; }
inline void dfs(int u){
for(int i=head[u];i!=-;i=a[i].Next)
{
int v=a[i].to;
if(v!=fa[u][]){
dfs(v);
f[u]+=f[v];
}
}
}
int main(){
init();
cin>>n>>m;
for(int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addv(u,v);
addv(v,u);
}
bfs();
for(int i=;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
f[u]++;
f[v]++;
f[lca(u,v)]-=;
// printf("lca %d\n",lca(u,v));
}
dfs();
ll ans=;
for(int i=;i<=n;i++)
{
// cout<<i<<" "<<f[i]<<endl;
if(f[i]==){
ans+=m;
}else if(f[i]==){
ans++;
}
}
cout<<ans<<endl; }
Network
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 6736   Accepted: 1916

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

Source

poj3417 Network 树上差分+LCA的更多相关文章

  1. 树上差分 (瞎bb) [树上差分][LCA]

    做noip2015的运输计划写了好久好久写不出来   QwQ 于是先来瞎bb一下树上差分    混积分 树上差分有2个常用的功能: (1)记录从点i到i的父亲这条路径走过几次 (2)将每条路径(s,t ...

  2. 【COGS 2434】 暗之链锁 树上差分+LCA

    差分就是把一个值拆成许多差的和如 1 2 4 6 9 那么 把这个东西拆成 1 1 2 2 3 就是了,当然也可以理解为对一个问题分解为多个子问题并对其进行操作来得到原问题的答案. 树上差分就更玄妙了 ...

  3. BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 1388  Solved: 860 [Submit][Stat ...

  4. [NOIP2015]运输计划(树上差分+LCA+二分)

    Description 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球. 小 P 掌管 ...

  5. NOIP2016 Day1 T2 天天爱跑步(树上差分,LCA)

    原文链接 原题链接 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏 ...

  6. poj3417 Network 树形Dp+LCA

    题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...

  7. BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA

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

  8. POJ3417(树上差分)

    会卡vector. ; int n, m, Ans; ], to[maxn * ], tot; int vis[maxn], f[maxn]; int d[maxn], sum[maxn]; vect ...

  9. Wannafly Camp 2020 Day 1E 树与路径 - 树上差分,LCA

    #include <bits/stdc++.h> using namespace std; #define int long long const int N = 1000005; vec ...

随机推荐

  1. Python05 函数

    待更新... 2018-4-16 09:00:30

  2. Eclipse右击jsp没有运行选项

    maven项目低级错误,没有更新maven资源库.....更新后就运行起来了

  3. OpenCV---resize

    转自http://www.cnblogs.com/korbin/p/5612427.html 在图像处理过程中,有时需要把图像调整到同样大小,便于处理,这时需要用到图像resize() 原函数void ...

  4. SqlDataAdapter 批量更新数据库表

    在数据库中批量插入数据许多人都已经了解了,就是使用.net 中的SqlBulkCopy对象(MSDN详解).我们在做评教系统的时候使用过这个对象,它能将数据表批量导入到数据库中,效率比单条插入数据效率 ...

  5. Solidity oraclize 常用数据源

    1. 股票数据: https://blog.quandl.com/api-for-stock-data iextrading.com www.nowapi.com 中文 2. 外汇数据: https: ...

  6. if else的执行流程

    int main(void) { int a, b; char op; float ans; scanf_s("%d%c%d",&a,&op,1,&b); ...

  7. 数字图像处理实验(16):PROJECT 06-03,Color Image Enhancement by Histogram Processing 标签: 图像处理MATLAB 2017

    实验要求: Objective: To know how to implement image enhancement for color images by histogram processing ...

  8. tensorflow rank

    可把tensorflow 中的tensor 理解为一个n维数组或列表, tensor 为静态变量,拥有动态维度.在tf中, 只有tensor能在节点和图计算中传递.

  9. laravel的mvc

  10. html5操作类名API——classlist

    tagNode.classList.add('123'); // 添加类 tagNode.classList.remove('bbb'); // 删除类 tagNode.classList.toggl ...