题意:

      给你一棵树和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. python flask框架详解

    Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务.本文参考自Flask官方文档, 英文不好的同学也可以参考中文文档 1.安装flask pi ...

  2. 【RocketMQ源码分析】深入消息存储(1)

    最近在学习RocketMQ相关的东西,在学习之余沉淀几篇笔记. RocketMQ有很多值得关注的设计点,消息发送.消息消费.路由中心NameServer.消息过滤.消息存储.主从同步.事务消息等等. ...

  3. Java视频教程免费分享(网盘直接取)

    Java基础 Java马士兵:链接:https://pan.baidu.com/s/1jJRvxGi密码:v3xb Java刘意:链接:https://pan.baidu.com/s/1kVZQCqr ...

  4. 在vscode中go编码发生的问题整理

    引言 使用VsCode进行Go程序开发,我们肯定会碰到一些问题,这些问题有些是IDE的配置问题,有些是下载包的版本不一致问题,本文主要针对在开发过程中碰到的问题做一个简单的回顾和整理. 前期准备,必看 ...

  5. 17. vue-route详细介绍

    前后端路由的来历 前端如何实现页面跳转但是不刷新? 了解hash和history两种方法 vue-router基本使用 安装vue-router 搭建vue-router框架的步骤 vue-route ...

  6. WebGPU[4] 纹理三角形

    代码见:https://github.com/onsummer/my-dev-notes/tree/master/webgpu-Notes/04-texture-triangle 原创,发布日 202 ...

  7. ELK查询命令详解总结

    目录 ELK查询命令详解 倒排索引 倒排索引原理 分词器介绍及内置分词器 使用ElasticSearch API 实现CRUD 批量获取文档 使用Bulk API 实现批量操作 版本控制 什么是Map ...

  8. 复制文件--cp

    cp file1 file2    将文件拷贝到指定路径下 cp -r dir1 dir2  将文件夹拷贝到指定路径下

  9. 轻松理解 Spring AOP

    目录 Spring AOP 简介 Spring AOP 的基本概念 面向切面编程 AOP 的目的 AOP 术语和流程 术语 流程 五大通知执行顺序 例子 图例 实际的代码 使用 Spring AOP ...

  10. 通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

    目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实现一个简单的基于.net的微服务电商系统(二)--通讯框架讲解 三.通过Dapr实现一个简单的基于.net的微服务电 ...