传送门

分析

首先我们知道如果在一棵树上加一条边一定会构成一个环,而删掉环上任意一条边都不改变连通性。我们把这一性质扩展到这个题上不难发现如果一条树边不在任意一个新边构成的环里则删掉这条边之后可以删掉任意一条新边,对方案数的贡献是m。而如果它只在一个新边构成的环中则要删除这条边和对应的新边,对方案数的贡献是1。而如果它在至少两个新边构成的环中则无论如何也不能将图分成两半,所以对方案数的贡献为0。在知道这些之后我们考虑如何维护一条边在几个由新边构成的环中,那我们自然考虑到了LCA,对于每一条新边将其LCA路径上的边的值都加1.所以我们只需要维护这个值就行了。据说可以用倍增+差分维护,但我并不会,我是用树剖维护的。我们考虑对于原来的树,除根节点外的每一个点入度一定为1,所以我们不在边上累加答案,而用这条边连接的两个点中深度较深的点来代表这条边,最后用2~n这几个点上的值便可以求出方案数。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int LOG = ;
vector<int>v[];
int ans,id[],col[],n,m;
int son[],siz[],cnt,dep[],fa[],acc[];
inline void dfs(int x,int la){
int maxn=;siz[x]=;
for(int i=;i<v[x].size();i++)
if(v[x][i]!=la){
fa[v[x][i]]=x;
dep[v[x][i]]=dep[x]+;
dfs(v[x][i],x);
siz[x]+=siz[v[x][i]];
if(siz[v[x][i]]>maxn){
maxn=siz[v[x][i]];
son[x]=v[x][i];
}
}
return;
}
inline void dfs2(int x,int ac){
id[x]=++cnt;
acc[x]=ac;
if(!son[x])return;
dfs2(son[x],ac);
for(int i=;i<v[x].size();i++)
if(v[x][i]!=fa[x]&&v[x][i]!=son[x])
dfs2(v[x][i],v[x][i]);
return;
}
inline void update(int le,int ri,int wh,int x,int y,int k){
if(x>y)return;
if(le>=x&&ri<=y){
col[wh]+=k;
return;
}
int mid=(le+ri)>>;
if(col[wh]){
col[wh<<]+=col[wh];
col[wh<<|]+=col[wh];
col[wh]=;
}
if(mid>=x)update(le,mid,wh<<,x,y,k);
if(mid<y)update(mid+,ri,wh<<|,x,y,k);
return;
}
inline int q(int le,int ri,int wh,int pl){
if(le==ri)return col[wh];
int mid=(le+ri)>>,ans;
if(col[wh]){
col[wh<<]+=col[wh];
col[wh<<|]+=col[wh];
col[wh]=;
}
if(mid>=pl)ans=q(le,mid,wh<<,pl);
else ans=q(mid+,ri,wh<<|,pl);
return ans;
}
inline void solve(int x,int y){
while(acc[x]!=acc[y]){
if(dep[acc[x]]<dep[acc[y]])swap(x,y);
update(,n,,id[acc[x]],id[x],);
x=fa[acc[x]];
}
if(id[x]>id[y])swap(x,y);
update(,n,,id[x]+,id[y],);
return;
}
int main(){
int i,j,k;
scanf("%d%d",&n,&m);
for(i=;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
fa[]=,dep[]=;
dfs(,);
dfs2(,);
for(i=;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
solve(x,y);
}
for(i=;i<=n;i++){
int x=q(,n,,id[i]);
if(x==)ans+=m;
else if(x==)ans+=;
}
printf("%d\n",ans);
return ;
}

loj10131 暗的连锁的更多相关文章

  1. LOJ10131暗的连锁

    题目描述 原题来自:POJ 3417 Dark 是一张无向图,图中有 N 个节点和两类边,一类边被称为主要边,而另一类被称为附加边.Dark 有 N–1 条主要边,并且 Dark 的任意两个节点之间都 ...

  2. LOJ #10131 「一本通 4.4 例 2」暗的连锁

    LOJ #10131 「一本通 4.4 例 2」暗的连锁 给一棵 \(n\) 个点的树加上 \(m\) 条非树边 , 现在需要断开一条树边和一条非树边使得图不连通 , 求方案数 . $n \le 10 ...

  3. LOJ10131. 「一本通 4.4 例 2」暗的连锁【树上差分】

    LINK solution 很简单的题 你就考虑实际上是对每一个边求出两端节点分别在两个子树里面的附加边的数量 然后这个值是0第二次随便切有m种方案,如果这个值是1第二次只有一种方案 如果这个值是2或 ...

  4. 倍增法求lca:暗的连锁

    https://loj.ac/problem/10131 #include<bits/stdc++.h> using namespace std; struct node{ int to, ...

  5. LOJ P10131 暗的连锁 题解

    每日一题 day27 打卡 Analysis 对于每条非树边 , 覆盖 x 到 LCA 和 y到 LCA 的边 , 即差分算出每个点和父亲的连边被覆盖了多少次 .被覆盖 0 次的边可以和 m 条非树边 ...

  6. POJ3417 Network暗的连锁 (树上差分)

    树上的边差分,x++,y++,lca(x,y)-=2. m条边可以看做将树上的一部分边覆盖,就用差分,x=1,表示x与fa(x)之间的边被覆盖一次,m次处理后跑一遍dfs统计子树和,每个节点子树和va ...

  7. LuoguP3128 [USACO15DEC]最大流Max Flow (树上差分)

    跟LOJ10131暗的连锁 相似,只是对于\(lca\)节点把它和父亲减一 #include <cstdio> #include <iostream> #include < ...

  8. loj题目总览

    --DavidJing提供技术支持 现将今年7月份之前必须刷完的题目列举 完成度[23/34] [178/250] 第 1 章 贪心算法 √ [11/11] #10000 「一本通 1.1 例 1」活 ...

  9. CSU训练分类

    √√第一部分 基础算法(#10023 除外) 第 1 章 贪心算法 √√#10000 「一本通 1.1 例 1」活动安排 √√#10001 「一本通 1.1 例 2」种树 √√#10002 「一本通 ...

随机推荐

  1. PHP JSON文件解析并获取key、value,判断key是否存在

    /****************************************************************************** * PHP JSON文件解析并获取key ...

  2. 使用range()生成自然数序列

  3. UVALive - 3211 Now or later (二分+2SAT)

    题目链接 题意:有n架飞机,每架飞机有两个着陆时间点可以选,要求任意两架飞机的着陆时间之差不超过k,求k的最大值. 解法:由于每架飞机都有两个选择,并且必选且只能选其中一个,时间冲突也是发生在两架飞机 ...

  4. SQL夯实基础(六):MqSql Explain

    关系型数据库中,互联网相关行业使用最多的无疑是mysql,虽然我们C# Developer很多用的都是sql server ,但是学习一些mysql方面的知识也是必要的,他山之石么. 先上一个expl ...

  5. VC 6.0下载 VC 6.0英文版下载 Visual C++ 6.0 英文企业版 集成SP6完美版(最新更新地址,百度网盘)

    下载地址1:Visual.C++.6.EN 下载地址2:Visual.C++.6.EN 更新下载地址可用(百度网盘)Visual.C++.6.EN 转载请注明出处,有技术问题,欢迎互相交流,或者留言.

  6. zabbix监控进程

    参考http://chenx1242.blog.51cto.com/10430133/1837990 1 前期说明 zabbix_server查看“文件在后台运行数量”所对应的key就是:proc.n ...

  7. [置顶] C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    头文件:#include <stdlib.h> atoi() 函数用来将字符串转换成整数(int),其原型为: int atoi (const char * str); [函数说明]ato ...

  8. 基于RFC5321使用ncat发送邮件

    今天和同事学习到的这个方法,学习了,记录一下: [root@localhost ~]# ncat TeamServer.localdomain ESMTP Postfix EHLO l00.win - ...

  9. centos6 安装teamviewer

    wget http://www.teamviewer.com/download/teamviewer_linux.rpm yum -y install temviewerX.rpm 机器最好联网,能够 ...

  10. Vue指令学习

    # new Vue({ vue所有的数据都是放到data里面的 # data:{ vue对象的数据 # a:1,对象 # b:[] , # } # methods:{vue对象的方法 # dosomt ...