题目:http://poj.org/problem?id=3417

根据一条边被几个环覆盖来判断能不能删、有几种情况等;

用树上差分,终点 s++,LCA s-=2,统计时计算子树s值的和即可;

用ST表做LCA,不知为何WA了:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const MAXN=1e5+;
int n,m,head[MAXN],ct,dep[MAXN],pre[MAXN][],s[MAXN];
long long ans;
struct N{
int to,next;
N(int t=,int n=):to(t),next(n) {}
}edge[MAXN<<];
void dfs(int x,int f)
{
dep[x]=dep[f]+;
pre[x][]=f;
for(int i=head[x];i;i=edge[i].next)
if(edge[i].to!=f)dfs(edge[i].to,x);
}
void init()
{
dfs(,);
for(int k=;k<=;k++)
for(int i=;i<=n;i++)
pre[i][k]=pre[pre[i][k-]][k-];
}
int lca(int x,int y)
{
if(dep[x]>dep[y])swap(x,y);
int d=dep[y]-dep[x];
for(int i=;i<=;i++)
if(/*d&(1<<i)*/(d>>i)&)y=pre[y][i];
for(int i=;i>=;i--)
if(pre[x][i]!=pre[y][i])
{
x=pre[x][i];
y=pre[y][i];
}
return pre[x][];
}
long long dfs2(int x,int f)
{
long long sum=s[x];
for(int i=head[x],u;i;i=edge[i].next)
{
if((u=edge[i].to)==f)continue;
long long k=dfs2(u,x);
if(k==)ans+=m;
if(k==)ans++;
sum+=k;
}
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y;i<n;i++)
{
scanf("%d%d",&x,&y);
edge[++ct]=N(y,head[x]);head[x]=ct;
edge[++ct]=N(x,head[y]);head[y]=ct;
}
init();
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(x==y)continue;
s[x]++;s[y]++;
s[lca(x,y)]-=;
}
dfs2(,);
printf("%lld",ans);
return ;
}

ST表为什么WA

于是改成了tarjan,过程中求答案;

注意非树边加边时判掉x=y的情况。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const MAXN=1e5+;
int n,m,head[MAXN],ct,s[MAXN],fa[MAXN],ct2,head2[MAXN];
long long ans;
bool vis[MAXN];
struct N{
int to,next;
N(int t=,int n=):to(t),next(n) {}
}edge[MAXN<<],ed[MAXN<<];
int find(int x)
{
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
void tarjan(int x)
{
fa[x]=x;vis[x]=;
for(int i=head2[x],u;i;i=ed[i].next)
if(vis[u=ed[i].to])s[find(u)]-=;
for(int i=head[x],u;i;i=edge[i].next)
{
if(vis[u=edge[i].to])continue;//fa
tarjan(u);fa[u]=x;s[x]+=s[u];
if(s[u]==)ans+=m;
if(s[u]==)ans++;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y;i<n;i++)
{
scanf("%d%d",&x,&y);
edge[++ct]=N(y,head[x]);head[x]=ct;
edge[++ct]=N(x,head[y]);head[y]=ct;
}
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(x==y)continue;//!
s[x]++;s[y]++;
ed[++ct2]=N(y,head2[x]);head2[x]=ct2;
ed[++ct2]=N(x,head2[y]);head2[y]=ct2;
}
tarjan();
printf("%d",ans);
return ;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Maven plugin提示错误“Plugin execution not covered by lifecycle configuration”

    myeclipse在其POM文件的一处提示出错如下: Plugin execution not covered by lifecycle configuration: org.apache.maven ...

  2. shell(2):正则表达式

    一.整理正则表达式博客 (1)正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 在linux中,通配符是由shel ...

  3. c++对象模型和对象内存布局

    简单对象模型:如下图所示: 每一个object是一系列的slots,每一个data member或者function member都有自己的一个slot.这种模型的空间和执行效率都很低.在这个模型中, ...

  4. 转载---- 使用opencv源码自己编制android so库的过程

    http://blog.csdn.net/lantishua/article/details/21182965 工作需要,在Android上使用OpenCV.opencv当前的版本(2.4.8)已经有 ...

  5. 深度解析开发项目之 03 - enum的使用

    深度解析开发项目之 03 - enum的使用 01 - 在#import和@interface之间定义typedef enum 注意: 默认是0,1,2,3 02 - 定义可以操作的数据类型的属性 0 ...

  6. 深入Garbage First垃圾收集器(三)G1中的垃圾收集

    G1 GC在收集暂停的过程中会回收绝大部分堆分区,唯一的例外是多级并发标记期间的清除阶段. 在清除阶段,如果G1遇到仅仅只存放了垃圾的分区,它就会立刻收集这些分区并将它们放回空闲分区列表中,因此这些分 ...

  7. Python 007- python的各种函数

    1.chr().unichr()和ord() chr()函数用一个范围在range(256)内的(就是0-255)整数作参数,返回一个对应的字符. unichr()跟它一样,只不过返回的是Unicod ...

  8. FeatureLayer.MODE_SNAPSHOT限制数量问题

    我在加载FeatureLayer的时候,采用MODE_SNAPSHOT模式,发现有的图层少了一些数据,改回MODE_ONDEMAND又正常. 究其原因,MODE_SNAPSHOT 是一次性将数据从服务 ...

  9. 【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性

    [BZOJ2216][Poi2011]Lightning Conductor Description 已知一个长度为n的序列a1,a2,...,an.对于每个1<=i<=n,找到最小的非负 ...

  10. EasyDarwin手机直播是如何实现的快速显示视频的方法

    前言 经常有人提到最近比较火的映客直播.花椒直播这种,是如何做到在打开手机直播中的某一个主播房间后,立即就能显示出主播视频,非常非常快,而且延时也比较小,是怎么做到的? 其实,这并不是什么高深的技术, ...