思路:首先来说,给一个树加一条边肯定要构成一个环,我们假设加了该边后产生的环上的每一条边都累计加一。

假设这条边是a到b,那么其实就是原树a->lca(a,b)到b->lca(a,b)上的边累计加一。

这个有什么用呢?

第一:当原树上某一条边的累加值为0时,也就是这一条边与所有的假边都没有构成环,那么你只要把这一条边删除了,再任意删除一条假边,肯定把图分成两份。答案+M

第二:当原树上某一条边的累加值为1时,也就是说原树上的这条边,有且仅有一条假边与他构成了环,那么此时将这条边与他对应的假边删除即可,原树上的这条边也只有这一种情况可以分成两份。答案+1

第三:当原树上某一条边的累加值大于等于2时,因为你始终只能删除一条假边,所以删除该原边对应的情况无论如何都无法将他分成两部分。答案+0

所以将M条边跑一边找到lca并且进行累加即可求出答案,但是问题就是怎么来进行这个累加,这里就用到了类似前缀和的方式或者dp的方式来求:用dif数组记录每一次累加的段,然后再用过一次dfs来将状态进行转换。

dif[x]++,dif[y]++,dif[lca(x,y)]-=2;

sta数组表示累加后的结果:

int dfs(int u)
{sta[u]=dif[u];for(int i=head[u];~i;i=edge[i].p){int v=edge[i].to;if(v==f[u][0]) continue;sta[u]+=dfs(v);//递归下去}return sta[u];
}

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define PI 3.14159265358979323846
#define me(a,b) memset(a,b,sizeof(a))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
#define pii make_pair
const int dir[4][2]= {0,-1,-1,0,0,1,1,0};
typedef long long ll;
const ll inFF=9223372036854775807;
typedef unsigned long long ull;
using namespace std;
const int maxn=1e5+5;
int f[maxn][33],d[maxn],dif[maxn],head[maxn],sta[maxn];
int sign,n,m;
struct node
{int to,p;
}edge[maxn<<1];
void add(int u,int v)
{edge[sign]=node{v,head[u]};head[u]=sign++;
}
void init()
{memset(dif,0,sizeof(dif));sign=0;for(int i=0;i<=n;i++)head[i]=-1;
}
void lca_dfs(int u)
{for(int i=1;(1<<i)<=n;i++)f[u][i]=f[f[u][i-1]][i-1];for(int i=head[u];~i;i=edge[i].p){int v=edge[i].to;if(v==f[u][0]) continue;f[v][0]=u;d[v]=d[u]+1;lca_dfs(v);}
}
int dfs(int u)
{sta[u]=dif[u];for(int i=head[u];~i;i=edge[i].p){int v=edge[i].to;if(v==f[u][0]) continue;sta[u]+=dfs(v);}return sta[u];
}
int lca(int a,int b)
{if(d[a]<d[b]) swap(a,b);int x=d[a]-d[b];for(int i=0;(1<<i)<=x;i++)if((1<<i)&x) a=f[a][i];if(a!=b){for(int i=(int)log2(n);i>=0;i--)if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];a=f[a][0];}return a;
}
int main()
{int x,y;while(cin>>n>>m){init();for(int i=1;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);d[1]=0,f[1][0]=1;lca_dfs(1);for(int i=1;i<=m;i++){scanf("%d %d",&x,&y);dif[x]++,dif[y]++,dif[lca(x,y)]-=2;}dfs(1);int ans=0;for(int i=1;i<=n;i++){if(sta[i]==0&&i!=1) ans+=m;if(sta[i]==1) ans+=1;}printf("%d\n",ans);}return 0;
}

POJ - 3417 Network LCA+树上差分相关推荐

  1. POJ - 3417 Network(树上差分)

    题目链接:点击查看 题目大意:(摘自大蓝书)Dark是人类内心的黑暗的产物,古今中外的勇者们都试图打倒它.经过研究,你发现Dark呈现无向图的结构,图中有N个节点和两类边,一类边被称为主要边,而另一类 ...

  2. POJ 3417 Network

    本文转载:http://www.cnblogs.com/YoungNeal/p/8530398.html 题目大意: 给定一棵树,有 n-1 条树边,m 条非树边,有两次割边的机会,第一次只能割树边, ...

  3. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  4. HDU - 5452 Minimum Cut(LCA+树上差分)

    题目链接:点击查看 题目大意:给出n个点,n-1条边组成一棵树,然后再给出m-n-1条边,组成一个图,现在要让我们求最少删去几条边才能让整个图不连通,并且要求只能在树上删去最多一条边 题目分析:这个题 ...

  5. P2680-运输计划【LCA,树上差分,二分答案】

    正题 题目链接:https://www.luogu.org/problemnew/show/P2680 题目大意 一棵带权无根树,给出若干条路径.选择一条边使其边权变为0,要求路径的长度的最大值最小. ...

  6. 【HDU - 5452】Minimum Cut(树形dp 或 最近公共祖先lca+树上差分,转化tricks,思维)

    题干: Given a simple unweighted graph GG (an undirected graph containing no loops nor multiple edges) ...

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

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

  8. [JLOI2014]松鼠的新家 倍增LCA+树上差分

    题目描述 题目 本来想写一道Tarjan的,结果发现这题倍增比较好写 这题主要要搞懂树上差分这东西(NOIP前这东西卡了我好久) 大概要注意的就是对于除了出发点以外的所有点都是重复算了的,所以最后要有 ...

  9. 松鼠的新家 LCA + 树上差分

    题意 中文题意就不需要分析了吧 分析 首先两点之间,我们应该去走最短路径最能得到最优解,所以很容易想到求LCA,假设两点分别为x,y,LCA(x,y) = u,所以只需要把路径 x -> u - ...

最新文章

  1. vba和python哪个好学-Python或将取代VBA,成为Excel官方脚本语言???
  2. Yarn取代job/task tracker
  3. Feature Pyramid Networks for Object Detection 论文笔记
  4. python06: 运算符. if
  5. 多模态融合算法——Multimodal Compact Bilinear Pooling
  6. ORA-12514, TNS:listener does not currently know of service requested in connect descriptor
  7. SAP License:SAP S4HANA和ECC的区别
  8. xxx.app已损坏,打不开.你应该将它移到废纸篓-已解决
  9. Error 1606 Could Not Access Network Location %SystemDrive%/inetpub/wwwroot/ 的错误解决方法
  10. Vmware安装Vmware Tools工具
  11. 小米手机计算机usb连接,小米手机连接电脑不显示usb选项
  12. (转载)yocto相关class总结
  13. 踩坑记32 vue3 拖拽边缘调整侧边栏宽度 拖拽条组件 宽度限制
  14. python输入一个整数和一个字符_【python零基础入门】基础语法之变量、字符串、数字、规则。...
  15. chatgpt:栅格化原理和代码
  16. 苹果的「AI 建筑师」GAUDI:根据文本生成 3D 场景
  17. Python和VizViewer进行自动驾驶数据集可视化
  18. 命令行常用工具的替代品
  19. Java写时复制CopyOnWriteArrayList
  20. photoshop二次开发python_PhotoShop工具开发之Python(二)

热门文章

  1. Java / Android String.format 的使用
  2. Android 获取联网的IP地址
  3. Ubuntu 安装 IPython、jupyter notebook
  4. 安装centos 7 桌面
  5. 【转】jQuery获取Select option 选择的Text和Value
  6. 29个简单直观的移动设备网页设计
  7. 从瀑布模型、极限编程到敏捷开发
  8. 用户控件和服务器控件的数据绑定
  9. java停车管理系统中期检查_java毕业设计_springboot框架的停车场收费管理系统
  10. android游戏课程设计,Miuka「游戏化课程设计」图卡18|好课程如何讲故事的