题意:

      给你一棵树和m条边,问你在这些边里面最多能够挑出多少条边,使得这些边之间不能相互交叉。

思路:

     lca+贪心,首先对于给的每个条边,我们用lca求出他们的公共节点,然后在公共节点的深度排序,排序之后我们先从最深的开始,每次判断当前的这条边的两点是否用过,如果没用过,那么就把以当前两点的公共点为树根的子树全部标记上,然后答案+1,就这样一直遍历到最后就行了,一开始敲了一个,TLE了,各种优化之后还是TLE了,最后没办法了,用了一下自己存的一个LCA的模板,这个比我自己写的LCA快,所以就AC了,思路就是贪心+LCA。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm> #define MAXN 110000
#define MAXM 210000

using namespace
std;
//*********************************************************
int n;
struct
EDGE
{
int
v, next, w;
}
edge[MAXM];
int
head[MAXN], e;
int
index, tmpdfn;
int
f[2 * MAXN], id[MAXN], vis[MAXN], pos[MAXN], dis[MAXN];
int
mi[2 * MAXN][18];
void
init()
{

memset(head, -1, sizeof(head));
e = 0;
index = tmpdfn = 0;
memset(vis, 0, sizeof(vis));
dis[1] = 0;
}
void
add(int u, int v, int w)
{

edge[e].v = v;
edge[e].w = w;
edge[e].next = head[u];
head[u] = e++;
}
void
dfs(int u)
{

vis[u] = 1;
int
tmp = ++tmpdfn;
f[++index] = tmp;
id[tmp] = u;
pos[u] = index;
for(int
i = head[u]; i != -1; i = edge[i].next)
{
int
v = edge[i].v;
if(!
vis[v])
{

dis[v] = dis[u] + edge[i].w;
dfs(v);
f[++index] = tmp;
}
}
}
void
rmqinit(int n, int *w)
{
for(int
i = 1; i <= n; i++) mi[i][0] = w[i];
int
m = (int)(log(n * 1.0) / log(2.0));
for(int
i = 1; i <= m; i++)
for(int
j = 1; j <= n; j++)
{

mi[j][i] = mi[j][i - 1];
if(
j + (1 << (i - 1)) <= n) mi[j][i] = min(mi[j][i], mi[j + (1 << (i - 1))][i - 1]);
}
}
int
rmqmin(int l,int r)
{
int
m = (int)(log((r - l + 1) * 1.0) / log(2.0));
return
min(mi[l][m] , mi[r - (1 << m) + 1][m]);
}
int
LCA(int l, int r)
{
if(
pos[l] > pos[r]) swap(l, r);
int
ans = rmqmin(pos[l], pos[r]);
return
id[ans];
}

//**********************************************************
typedef struct
{
int
a ,b ,ggdeep ,lca;
}
EDGEE; EDGEE edgee[110000]; bool camp(EDGEE a ,EDGEE b)
{
return
a.ggdeep > b.ggdeep;
} int
use[110000]; void mk_dfs(int x)
{

use[x] = 1;
for(int
k = head[x] ;k + 1 ;k = edge[k].next)
{
int
to = edge[k].v;
if(
use[to] || dis[x] + 1 != dis[to]) continue;
mk_dfs(to);
}
} int main()
{
int
u, v, w, l, r ,m;
while(~
scanf("%d%d", &n, &m))
{
init();
for(int
i = 1 ;i < n ;i ++)
{

scanf("%d %d" ,&u ,&v);
add(u ,v ,1);
add(v ,u ,1);
}
for(int
i = 1 ;i <= m ;i ++)
scanf("%d %d" ,&edgee[i].a ,&edgee[i].b);
dfs(1);
rmqinit(index, f);
for(int
i = 1 ;i <= m ;i ++)
{
int
lca = LCA(edgee[i].a ,edgee[i].b);
edgee[i].ggdeep = dis[lca];
edgee[i].lca = lca;
}
sort(edgee + 1 ,edgee + m + 1 ,camp);
memset(use ,0 ,sizeof(use));
int
ans = 0;
for(int
i = 1 ;i <= m ;i ++)
{ if(
use[edgee[i].a] || use[edgee[i].b])
continue;

ans ++;
mk_dfs(edgee[i].lca);
}

printf("%d\n" ,ans);
}
return
0;
}

hdu4912 LCA+贪心的更多相关文章

  1. 【BZOJ-4082】Surveillance 树链剖分 LCA + 贪心

    4082: [Wf2014]Surveillance Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 260  Solved: 100[Submit][ ...

  2. HDU 4912 LCA + 贪心

    题意及思路 说一下为什么按LCA深度从深到浅贪心是对的.我们可以直观感受一下,一条的路径会影响以这个lca为根的这颗树中的链,而深度越深,影响范围越小,所以先选影响范围小的路径. #include & ...

  3. HDU 4912 lca贪心

    Paths on the tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  4. ZOJ - 4048 Red Black Tree (LCA+贪心) The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online

    题意:一棵树上有m个红色结点,树的边有权值.q次查询,每次给出k个点,每次查询有且只有一次机会将n个点中任意一个点染红,令k个点中距离红色祖先距离最大的那个点的距离最小化.q次查询相互独立. 分析:数 ...

  5. BZOJ 1787: [Ahoi2008]Meet 紧急集合(lca+贪心)

    [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 2 4 4 ...

  6. HDU 4912 Paths on the tree(LCA+贪心)

    题目链接 Paths on the tree 来源  2014 多校联合训练第5场 Problem B 题意就是给出m条树上的路径,让你求出可以同时选择的互不相交的路径最大数目. 我们先求出每一条路径 ...

  7. Codevs 1218 疫情控制 2012年NOIP全国联赛提高组

    1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...

  8. 【Never Stop】联赛集训记录

    始于10/01/2017. Day I: T2图论,没想到.T3谜一样DP(是从来没意识到还可以这样). rank10. 下午刷了点题,CDQ也只打出一个板子,感觉自己不在状态? ========== ...

  9. 2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)

    心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description 来,我们先来放松下,听听儿歌,一起“唱” ...

随机推荐

  1. HDOJ-3038(带权并查集)

    How many answers wrong HDOJ-3038 一个很好的博客:https://www.cnblogs.com/liyinggang/p/5327055.html #include& ...

  2. roarctf_2019_realloc_magic

    目录 roarctf_2019_realloc_magic 总结 题目分析 checksec 函数分析 解题思路 初步解题思路 存在的问题 问题解决方案 最终解决思路 编写exp exp说明 roar ...

  3. Docker 三剑客 到 k8s 介绍

    一.Docker 三剑客 Docker-Compose Docker-Compose 是用来管理你的容器的,有点像一个容器的管家,想象一下当你的Docker中有成百上千的容器需要启动,如果一个一个的启 ...

  4. WPF 基础 - 图片与 base64

    1. base64 转图片 将 base64 转成 byte[] 将 byte[] 作为内存流保存到一个 BitmapImage 实例的流的源 把 BitmapImage 作为目标图片的 Source ...

  5. 任务3 PHP配置 1. PHP基础配置

    查看PHP配置文件得位置 #/ucsr/local/php/bin/php -i |grep -i "loaded configuration file" # cp /usr/lo ...

  6. vue 给一个值重置初始值

    查了下资料很多都是如下: 1. this.$options.data() 这个可以获取原始的data值,this.$data 获取当前状态下的data,拷贝重新赋值一下就行了. 1 Object.as ...

  7. PTA 中序输出度为1的结点

    6-9 中序输出度为1的结点 (10 分)   本题要求实现一个函数,按照中序遍历的顺序输出给定二叉树中度为1的结点. 函数接口定义: void InorderPrintNodes( BiTree T ...

  8. 全量同步Elasticsearch方案之Canal

    一.前言 Canal 是阿里的一款开源项目,纯 Java 开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了 MySQL(也支持 mariaDB). Canal 除了支持 b ...

  9. Android Studio 之 TextView基础

    •引言 在开始本节内容前,先要介绍下几个单位: dp(dip) : device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关 一般我们为了支持 ...

  10. ZooKeeper 会话的秘密

    本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源.有趣.入门级的 ZooKeeper 教程,面向有编程基础的新手. 项 ...