poj3417Network【LCA】【树形DP】
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
感觉LCA真的是高深莫测
还是看的题解
原来的图是一棵树,新增的m条边
每增加一条,一定会构成一个u-lca(u,v)-v-u的一个环
每两个节点之间的边一定都会被一些环给覆盖 称为覆盖数
计算原图中每条边的覆盖数
如果覆盖数为0 那么这条边只要被删除,新图中任意删去一条边 整个network都会被分割
如果覆盖数为1 那么删除这条边和新图中对应的边 也会被分割
只有覆盖数为2 这两个点才不会被分割
用dp[u]表示节点u和他父亲相连的边的覆盖数
每增加一个新边(u, v)就使dp[u]++,dp[v]++ 而dp[lca(u, v)] -= 2
因为最后从根开始遍历,累加dp
dp[u]++后,路径u-lca(u,v)上的覆盖数都加上了,lca(u,v)到根节点的也被加上了,而实际上是不需要加的因为这条路径没有在环里
所以-2就行了
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <queue>
#include <stack>
#define inf 0x3f3f3f3f
using namespace std;
int n, m, ecnt;
const int maxn = 100005;
int dep[maxn], dp[maxn], parent[maxn][22];
struct node{
    int to, next;
}edge[2 * maxn];
int head[maxn];
bool vis[maxn];
void dfs(int u)
{
    vis[u] = true;
    for(int i = head[u]; ~i; i = edge[i].next){
        int v = edge[i].to;
        if(!vis[v]){
            parent[v][0] = u;
            dep[v] = dep[u] + 1;
            dfs(v);
        }
    }
}
void init()
{
    ecnt = 0;
    memset(head, -1, sizeof(head));
    memset(vis, 0, sizeof(vis));
    memset(dep, 0, sizeof(dep));
    memset(parent, -1, sizeof(parent));
    memset(dp, 0, sizeof(dp));
}
void add(int u, int v)
{
    edge[ecnt].to = v;
    edge[ecnt].next = head[u];
    head[u] = ecnt++;
}
void rmq()
{
    for(int j = 1; (1 << j) <= n; j++){
        for(int i = 1; i <= n; i++){
            if(~parent[i][j - 1]){
                parent[i][j] = parent[parent[i][j - 1]][j - 1];
            }
        }
    }
}
int LCA(int a, int b)
{
    if(dep[a] < dep[b]) swap(a, b);
    int i;
    for(i = 0; (1 << i) <= dep[a]; i++);
    i--;
    for(int j = i; j >= 0; j--){
        if(dep[a] - (1 << j) >= dep[b]){
            a = parent[a][j];
        }
    }
    if(a == b){
        return a;
    }
    for(int j = i; j >= 0; j--){
        if(parent[a][j] != -1 && parent[a][j] != parent[b][j]){
            a = parent[a][j];
            b = parent[b][j];
        }
    }
    return parent[a][0];
}
void goto_dp(int u)
{
    vis[u] = true;
    for(int i = head[u]; ~i; i = edge[i].next){
        int v = edge[i].to;
        if(!vis[v]){
            goto_dp(v);
            dp[u] += dp[v];
        }
    }
}
int main()
{
    while(scanf("%d%d", &n, &m) != EOF){
        init();
        for(int i = 1; i < n; i++){
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v);
            add(v, u);
        }
        dfs(1);
        rmq();
        for(int i = 1; i <= m; i++){
            int u, v;
            scanf("%d%d", &u, &v);
            dp[u]++;
            dp[v]++;
            dp[LCA(u, v)] -= 2;
        }
        memset(vis, 0, sizeof(vis));
        goto_dp(1);
        int ans = 0;
        for(int i = 2; i <= n; i++){
            if(dp[i] == 0) ans += m;
            else if(dp[i] == 1) ans++;
        }
        printf("%d\n", ans);
    }
    return 0;
}
												
											poj3417Network【LCA】【树形DP】的更多相关文章
- poj3417 LCA + 树形dp
		
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
 - Codeforces Round #343 (Div. 2) E. Famil Door and Roads lca 树形dp
		
E. Famil Door and Roads 题目连接: http://www.codeforces.com/contest/629/problem/E Description Famil Door ...
 - HDU 4008 Parent and son LCA+树形dp
		
题意: 给定case数 给定n个点的树,m个询问 以下n-1行给出树边 m个询问 x y 问:以x为根.y子树下 y的最小点标的儿子节点 和子孙节点 思路: 用son[u][0] 表示u的最小儿子 s ...
 - [poj3417]Network(LCA+树形dp)
		
题意:给出一棵无根树,然后下面再给出m条边,把这m条边连上,每次你去两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 解题关键:边权转化为点权,记录每条边被环覆盖的次数,通过val[a] ...
 - 可恶!学了这么久的LCA,联考的题目却是LCA+树形DP!!!可恶|!!!这几天想学学树形DP吧!先来一道入门题HDU 1520 Anniversary party
		
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
 - poj3417 Network 树形Dp+LCA
		
题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...
 - hdu_5293_Tree chain problem(DFS序+树形DP+LCA)
		
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5293 被这题打蹦了,看着题解写的,很是爆炸,确实想不到,我用的DFS序+LCA+树形DP,当然也可以写 ...
 - 【BZOJ-3631】松鼠的新家       树形DP?+ 倍增LCA + 打标记
		
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1231 Solved: 620[Submit][Stat ...
 - Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]
		
题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...
 - HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
		
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
 
随机推荐
- Explore Basic Behavior of the TurtleBot ---3
			
原创博文:转载请标明出处(周学伟):http://www.cnblogs.com/zxouxuewei/tag/ Introduction 此示例帮助您使用turtlebot的自主性. 驱动机器人向前 ...
 - Get started with ros  -- 1
			
原创博文:转载请标明出处(周学伟):http://www.cnblogs.com/zxouxuewei/tag/ 一.Introduction: 机器人操作系统(ROS)是使机器人系统的不同部分能够发 ...
 - SpringBoot------使用Fastjson解析Json数据
			
方法一: 1.在pom.xml文件下添加依赖包 <dependency> <groupId>com.alibaba</groupId> <artifactId ...
 - SQLServer------备份与还原
			
转载: http://www.cnblogs.com/zgqys1980/archive/2012/07/04/2576382.html
 - libevent 入门教程:Echo Server based on libevent(转)
			
下面假定已经学习过基本的socket编程(socket, bind, listen, accept, connect, recv, send, close),并且对异步/callback有基本的认识. ...
 - 扩展方法(DateTableToList)
			
public static IList<T> ToList<T>(this DataTable dt) where T : class,new() { var prlist = ...
 - vue中使用mockjs
			
第一步安装mockjs:npm i mockjs -S 在src目录下新建mock文件夹,文件夹添加test.js test.js内容如下: import Mock from 'mockjs'; co ...
 - ios开发周期之--(向上,向下,四舍五入)取整
			
ceil(x)返回不小于x的最小整数值(然后转换为double型). floor(x)返回不大于x的最大整数值. round(x)返回x的四舍五入整数值.
 - laravel 5.3升级5.4
			
1)修改 composer 配置文件 composer.json 1.如果你用了 laravel-admin,larvel-admin 版本改 1.4.x-dev 2.laravel 版本改 5.4. ...
 - 第十七篇:IO复用之select实现
			
前言 在看过前文:初探IO复用后,想必你已对IO复用这个概念有了初步但清晰的认识. 接下来,我要在一个具体的并发客户端中实现它(基于select函数),使得一旦服务器中的客户进程被终止的时候,客户端这 ...