题意:

给定n个城市,和一些道路,道路有两种,一种是石头路,还有一种是乡村路,石头路形成了一棵树,即两两城市都可达,乡村路的加入使所有的石头路都处于一个或多个环中,即任意石头路被破坏后,城市间依然可以通过乡村路连通,现在敌国可以破坏一条石头路和一条乡村路,问,有多少种破坏方案,可以使破坏后,至少有一对城市不能互相到达。

题解:

仔细想想可以发现,石头路形成了一棵树,当这棵树上某一段道路被乡村路只覆盖一次时,那么破坏掉这条乡村路,这段路上的所有石头路破坏任意一条都能满足条件,所以只需要先把石头路形成的树剖分成链,然后用线段树来依次将乡村路往上覆盖,最后只需统计被覆盖次数为1的道路即为答案

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 2e4 + 10;
const int maxe = 1e5 + 10;
int fir[maxn], nxt[maxe<<1], edge[maxe<<1], cnt_edge;
void add_edge(int u, int v)
{edge[cnt_edge] = v;nxt[cnt_edge] = fir[u];fir[u] = cnt_edge++;edge[cnt_edge] = u;nxt[cnt_edge] = fir[v];fir[v] = cnt_edge++;
}int fa[maxn], son[maxn], sz[maxn], dep[maxn];
int id[maxn], top[maxn], num, root;
struct
{void init(){root = 1;fa[root] = num = dep[root] = 0;}void dfs(int u){sz[u] = 1; son[u] = 0;for (int i = fir[u]; i != -1; i = nxt[i]){int v = edge[i];if (v == fa[u]) continue;fa[v] = u; dep[v] = dep[u] + 1;dfs(v);sz[u] += sz[v];if (sz[son[u]] < sz[v]) son[u] = v;}}void build_tree(int u, int tp){id[u] = num++; top[u] = tp;if (son[u]) build_tree(son[u], top[u]);for (int i = fir[u]; i != -1; i = nxt[i]){int v = edge[i];if (son[u] == v || v == fa[u]) continue;build_tree(v, v);}}void run(){init();dfs(root);build_tree(root, root);num--;}
}div_chain;int n, m;
struct Road
{int u, v;Road(int u = 0, int v = 0) : u(u), v(v) {}}road[maxe];
int road_cnt;struct segment
{
#define lson o<<1, L, M
#define rson o<<1|1, M+1, Rint col[maxe<<2];void build(int o, int L, int R){col[o] = 0;if (L <= R) return ;int M = (L + R) >> 1;build(lson);build(rson);}void PushDown(int o){if (col[o]){col[o<<1] += col[o];col[o<<1|1] += col[o];col[o] = 0;}}void update(int p1, int p2, int v, int o, int L, int R){if (p1 <= L && p2 >= R){col[o] += v;return ;}PushDown(o);int M = (L + R) >> 1;if (p1 <= M) update(p1, p2, v, lson);if (p2 > M) update(p1, p2, v, rson);}void Find(int a, int b){int ta = top[a], tb = top[b];while (ta != tb){if (dep[ta] < dep[tb]){swap(ta, tb); swap(a, b);}update(id[ta], id[a], 1, 1, 1, num);a = fa[ta]; ta = top[a];}if (a == b) return;if (dep[a] < dep[b]){swap(a, b);}update(id[son[b]], id[a], 1, 1, 1, num);}int query(int o, int L, int R){if (L == R){if (col[o] == 1){return 1;}else return 0;}PushDown(o);int M = (L + R) >> 1;return query(lson) + query(rson);}}seg;
int main()
{//freopen("/Users/apple/Desktop/in.txt", "r", stdin);while (scanf("%d%d", &n, &m) != EOF){memset(fir, -1, sizeof(fir));cnt_edge = 0, road_cnt = 0;for (int i = 0; i < m; i++){int u, v, w; scanf("%d%d%d", &u, &v, &w);if (w == 1) add_edge(u, v);else road[road_cnt++] = Road(u, v);}div_chain.run();seg.build(1, 1, num);for (int i = 0; i < road_cnt; i++){seg.Find(road[i].u, road[i].v);}printf("%d\n", seg.query(1, 1, num));}return 0;
}

Acdream 1424 Diversion 树链剖分+线段树相关推荐

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  2. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  3. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  4. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  5. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  6. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  7. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  9. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. 计算机技术可以学音乐吗,音响工程师可以练出来吗?
  2. django mysql connector_MySQL Connector / Python作为Django引擎?
  3. linux程序调试命令strace
  4. Centos7 amp;amp; Docker amp;amp; Jenkins amp;amp; ASP.NET Core
  5. springboot超详细教程_超详细便当袋教程 || 特殊时期,自己带饭最安心!
  6. java获取当前月第一天和最后一天,上个月第一天和最后一天
  7. c# post 读取返回html_PHP GET与POST
  8. Centos6.5 Couchdb安装
  9. python可以下载百度文库_不用下载券也能下载百度文库资料,Python帮你轻松搞定...
  10. 单片机学习笔记(一)——概述
  11. outlook服务器邮件满了怎么办,Outlook邮箱不能接收邮件提示邮件箱已满的解决方法...
  12. 2021年12月国产数据库大事记-墨天轮
  13. gee微端服务器系统设置,Gee引擎微端服务器
  14. 联想电脑删除右键多余菜单选项
  15. Android中使用Toast弹出信息提示时的用户体验优化
  16. 基于STM32四轴飞控制作笔记
  17. IOS开发百度地图API入门到精通-用点生成路线,导航,气泡响应
  18. java创建动态二维数组
  19. 聊聊P2P网贷平台的风险【站在平台的角度】
  20. 零窗口探测怎么抓包_易语言防止助手探测窗口的代码

热门文章

  1. 聚合数据API接口调用方法
  2. python创始人国籍_2018年4月TIOBE排行榜前10的编程语言创始人
  3. js URL 地址参数格式化
  4. 2407 · 计算 a + aa + aaa + aaaa 的值(LintCode,Python,入门)
  5. Windows10 关闭传递优化
  6. 论文:Ref-NMS: Breaking Proposal Bottlenecks in Two-Stage Referring Expression Grounding
  7. 锻炼!!!!最佳时间!!!!希望大家都要记得锻炼身体!!!!
  8. POJ 3295: Tautology
  9. win7声音图标不见,此图标当前处于未活动状态
  10. java计算机毕业设计html5大众汽车网站MyBatis+系统+LW文档+源码+调试部署