一道LCA+树上差分

原题链接

显然每一条新增边都会导致环。

如果试着举些例子的话,很容易发现割掉非环上的边,则割掉其他任意一条新增边都可达成目标;若割掉的原有边是一个环上的边,那么只有割掉导致这个环出现的新增边才能使得图变为不连通的两部分。若割掉的边是两个或两个以上的环上的边,那么无论第二次怎么割都不可能达成目标。

也就是说,我们只要统计每一条原有边是几个环上的边,就可以直接枚举并计算方案个数。

可以直接通过树链剖分暴力计算,但这里我们可以用针对边的树上差分来解决,且跑的更快。

枚举每条新增边,设两端点为\(x,y\),则我们给节点\(x,y\)的权值加上\(1\),对节点\(LCA(x,y)\)的权值减去\(2\)。枚举完毕后用\(dfs\)求出\(f[x]\),表示以\(x\)为根的子树中所有节点的权值之和,而最后的\(f[x]\)实际上表示\(x\)与它父亲节点的这条边是几个环上的边,然后枚举所有原有边并统计答案即可。

\(LCA\)部分可以使用\(tarjan\),跑的更快些。

#include<cstdio>
using namespace std;
const int N = 1e5 + 10;
struct eg {
int x, y;
};
eg a[N];
struct dd {
int y, nex, id;
};
dd q[N << 1];
int fi[N], di[N << 1], ne[N << 1], f[N], fi_q[N], an[N], v[N], fa[N], l, lq;
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c<'0' || c>'9'; c = getchar())
p |= c == '-';
for (; c >= '0'&&c <= '9'; c = getchar())
x = x * 10 + (c - '0');
return p ? -x : x;
}
inline int fin(int x)
{
if (!(fa[x] ^ x))
return x;
return fa[x] = fin(fa[x]);
}
inline void add(int x, int y)
{
di[++l] = y;
ne[l] = fi[x];
fi[x] = l;
}
inline void add_q(int x, int y, int z)
{
q[++lq].y = y;
q[lq].nex = fi_q[x];
q[lq].id = z;
fi_q[x] = lq;
}
void tarjan(int x)
{
int i, y;
v[x] = 1;
for (i = fi[x]; i; i = ne[i])
{
y = di[i];
if (!v[y])
{
tarjan(y);
fa[y] = x;
}
}
for (i = fi_q[x]; i; i = q[i].nex)
{
y = q[i].y;
if (!(v[y] ^ 2))
an[q[i].id] = fin(y);
}
v[x] = 2;
}
void dfs(int x, int fa)
{
int i, y;
for (i = fi[x]; i; i = ne[i])
{
y = di[i];
if (y != fa)
{
dfs(y, x);
f[x] += f[y];
}
}
}
int main()
{
int i, n, m, x, y, s = 0;
n = re();
m = re();
for (i = 1, fa[n] = n; i < n; i++)
{
fa[i] = i;
x = re();
y = re();
add(x, y);
add(y, x);
}
for (i = 1; i <= m; i++)
{
a[i].x = re();
a[i].y = re();
if (!(a[i].x^a[i].y))
an[i] = a[i].x;
add_q(a[i].x, a[i].y, i);
add_q(a[i].y, a[i].x, i);
}
tarjan(1);
for (i = 1; i <= m; i++)
{
f[a[i].x]++;
f[a[i].y]++;
f[an[i]] -= 2;
}
dfs(1, 0);
for (i = 2; i <= n; i++)
{
if (!f[i])
s += m;
else
if (!(f[i] ^ 1))
s++;
}
printf("%d", s);
return 0;
}

POJ3417 Network的更多相关文章

  1. poj3417 Network 树形Dp+LCA

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

  2. poj3417 Network 树上差分+LCA

    题目传送门 题目大意:给出一棵树,再给出m条非树边,先割掉一条树边,再割掉一条非树边,问有几种割法,使图变成两部分. 思路:每一条 非树边会和一部分的树边形成一个环,分三种情况: 对于那些没有形成环的 ...

  3. [POJ3417]Network(LCA,树上差分)

    Network Description Yixght is a manager of the company called SzqNetwork(SN). Now she's very worried ...

  4. POJ3417 Network(算竞进阶习题)

    LCA + 树上差分(边差分) 由题目意思知,所有主要边即为该无向图的一个生成树. 我们考虑点(u,v)若连上一条附加边,那么我们切断(u,v)之间的主要边之后,由于附加边的存在,(u,v)之间的路径 ...

  5. [poj3417]Network(LCA+树形dp)

    题意:给出一棵无根树,然后下面再给出m条边,把这m条边连上,每次你去两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 解题关键:边权转化为点权,记录每条边被环覆盖的次数,通过val[a] ...

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

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

  7. [POJ3417]Network/闇の連鎖

    Description 传说中的暗之连锁被人们称为 Dark. Dark 是人类内心的黑暗的产物,古今中外的勇者们都试图打倒它.经过研究,你发现 Dark 呈现无向图的结构,图中有 N 个节点和两类边 ...

  8. poj3417 Network/闇の連鎖[树上差分]

    首先隔断一条树边,不计附加边这个树肯定是断成两块了,然后就看附加边有没有连着的两个点在不同的块内. 方法1:BIT乱搞(个人思路) 假设考虑到$x$节点隔断和他父亲的边,要看$x$子树内有没有点连着附 ...

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

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

随机推荐

  1. h5内容初探

    h5简介: h5新特性 h5新增标签 article  和  section 的区别相当于 div  和  p标签的区别 1—6都是块级元素 h5新增属性 拖放 拖动事件 <style> ...

  2. TensorFlow常用函数

    [1]卷积层(Convolutional Layer),构建一个2维卷积层,常用的参数有 conv = tf.layers.conv2d( inputs=pool, filters=64, kerne ...

  3. Spring-session redis 子域名 session

    Spring-session & redis 子域名共享session 例子: a.example.comb.example.comSpring 版本 4.2.6.RELEASE Spring ...

  4. Android 添加网络权限

    [Android 添加网络权限] <uses-permission Android:name="android.permission.INTERNET"></us ...

  5. 【Scheme】树结构

    将表作为序列的表示方式,可以推广到元素本身也是序列的序列.例如,我们可以认为对象((1 2) 3 4)是通过(cons (list 1 2) (list 3 4))构造出来的. 这个表包含三个项,其中 ...

  6. springboot logback

    /resources/logback-spring.xml <configuration> <appender name="stdout" class=" ...

  7. IDEA错误:Cannot start compilation: the output path is not specified for module "Test". Specify the out

    错误是发生在从github上checkout自己的项目时.因为没有将配置文件一起上传,所以在运行Java程序时有了这个报错: Cannot start compilation: the output ...

  8. input type='number'时,maxlength属性无效

    <input type="number" oninput="if(value.length>11)value=value.slice(0,11)"  ...

  9. CentOS ./configure && make && make install详解

    码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install). 在Linux中利用源码包安装软件最重要的就是要仔细阅读安装包当中的README  INST ...

  10. 【模型】Toon Dragon

    下载地址:点击下载