lca

洛谷P4281 【[AHOI2008]紧急集合 / 聚会】

橙三吉。 提交于 2020-01-14 09:38:31
LCA题目 这题不就是改成三个点的LCA吗? 首先求出三个点中两两的LCA,如果有两个LCA相等,那么三个点的LCA就是另外那对点的LCA int fa1=lca(u,v),fa2=lca(v,w),fa3=lca(w,u); if(fa1==fa2)printf("%d ",fa3); if(fa2==fa3)printf("%d ",fa1); if(fa3==fa1)printf("%d ",fa2); 最后三个点深度和减去三个LCA的深度和就是金币数 看着他这么水就马上把代码 从我博客里弄下来改一改 交上去 #include<bits/stdc++.h> using namespace std; struct edge{ int to,next; }ed[100005]; int n,m,u,v,w,cnt,head[50005],dep[50005],f[50005][20]; void add(int u,int v){ cnt++; ed[cnt].to=v; ed[cnt].next=head[u]; head[u]=cnt; } void dfs(int u,int fa){ f[u][0]=fa; dep[u]=dep[fa]+1; for(int i=1;i<20;i++)f[u][i]=f[f[u][i-1]][i-1]; for(int i=head[u]

洛谷 2680 运输计划 题解

浪子不回头ぞ 提交于 2020-01-11 23:57:30
博客观赏效果更佳 题意简述 n n n 个点的边带权树,给 m m m 条关键的链。把树上一条边的权值变为0,使得 m m m 条链的和中,最大值最小。 n , m < = 1 e 5 n,m<=1e5 n , m < = 1 e 5 。 思路 二分最大值 k k k 。现在考虑如何检验一个 k k k 。 找到所有链和 > k >k > k 的链,设这里面最长的链长度为 S S S ,有 C C C 条这样的链。用树链剖分找到被所有 C C C 条链都覆盖的边。设边权为 w w w ,如果 S − w < = k S-w<=k S − w < = k ,又因为这条边被所有和 > k >k > k 的链都覆盖了,所以,将这条边边权设为 0 0 0 ,就珂以把所有和 > k >k > k 的链修♂正回来。那就满足条件了,检验结果为true。 然后就这样二分即珂。 关于如何求被所有链都覆盖的边 如果您足够明智,跳过这个部分好了。 开一颗临时的树,所有边权为 0 0 0 ,树链剖分维护:对于所有和 > k >k > k 的链 ( a , b ) (a,b) ( a , b ) ,在链上的边权都+1。 然后只要找边权 = C =C = C 的边即珂。 但是树链剖分维护的是点权,怎么把边权转化成点权呢?只要把一条边的权值,记录在这条边的儿子上即珂。然后我们对于链 ( u , v ) (u,v

51nod2621 树上距离一题四解ST表+倍增+Tarjan+树剖

一笑奈何 提交于 2020-01-08 05:41:42
LCA裸题 只有代码无原理,给自己复习用 1. ST表(这题2^10就够了) 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=2e3+50; 5 6 int cnt,dfn[maxn],dep[maxn],dp[maxn][21],lg2[maxn],dis[maxn],w[maxn][maxn]; 7 std::vector<int> G[maxn]; 8 void dfs(int u,int fa){ 9 dis[u]=dis[fa]+w[u][fa]; 10 dfn[u]=++cnt; dep[u]=dep[fa]+1; dp[cnt][0]=u; 11 for(int i=0,v;i<G[u].size();i++){ 12 if((v=G[u][i])==fa) continue; 13 dfs(v,u); 14 dp[++cnt][0]=u; 15 } 16 } 17 void st(){ 18 for(int i=2;i<=cnt;i++) lg2[i]=lg2[i>>1]+1; 19 for(int j=1;j<=20;j++){ 20 for(int i=1;i+(1<<j)-1<=cnt;i++){ 21 int r=i+(1<<(j-1)); 22 dp[i][j] =

gmoj 1914. 【2011集训队出题】最短路

删除回忆录丶 提交于 2019-12-28 04:42:13
题目描述 Description 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径。 Input 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个整数v,u,w表示一条无向边v-u,长度为w 最后Q行,每行两个整数v,u表示一组询问 Output 输出Q行,每行一个整数表示询问的答案 Sample Input 9 10 2 1 2 1 1 4 1 3 4 1 2 3 1 3 7 1 7 8 2 7 9 2 1 5 3 1 6 4 5 6 1 1 9 5 7 Sample Output 5 6 Data Constraint 对于5%的数据,N<=100 对于20%的数据,N<=1000 对于100%的数据,N<=10000,Q<=10000 题解 Solution 1 圆方树裸题(然而我不会) Solution 2 这应该是这题最水的解法了吧(好像是题解做法)! 发现这个仙人掌十分难搞,如果它是一棵树就容易处理了! 因此我们考虑怎么把仙人掌变成一棵树。 由于一条边最多只属于一个环,因此只用在每个环删除一条边,就可以变成一棵树了。 我们不妨以1号点为源点,跑一遍spfa,只保留那些更新到最短路的边,这就变成了一棵树。 这棵树有一个十分优良的性质:u,v两个点向上跳时,途经的所有环中,走树边是最优的(lca的那个环除外)

带花树算法

不羁岁月 提交于 2019-12-24 02:48:15
带花树算法 先放上大神的blog,个人认为没办法比这位dalao解释的更清楚。 带花树算法 在北京冬令营的时候,yby提到了“带花树开花”算法来解非二分图的最大匹配。 于是,我打算看看这是个什么玩意。其实之前,我已经对这个算法了解了个大概,但是。。。真的不敢去写。 有一个叫Galil Zvi的人(应该叫计算机科学家),写了篇论文: Efficient Algorithms for Finding Maximal Matching in Graphs (如果你在网上搜不到,可以: http://builtinclz.abcz8.com/art/2012/Galil%20Zvi.pdf ) 这篇论文真神啊,它解决了4个问题: (一般图+二分图)的(最大匹配+最大权匹配)问题。 算法的思想、故事,请自己看论文吧。 这个论文告诉了我们很多有趣的东西,例如: 用Dinic实现的二分图匹配的时间复杂度其实是O(M*N^0.5),这也许能够解释为什么一般网络流算法比Hungry要快了。 另外,带花树算法的正确性的证明比较困难;而其时间复杂度是可以做到O(M*N^0.5)的,不过要详细实现,那么就快能到“ACM最长论文奖”了。 我写了一个实例代码: http://builtinclz.abcz8.com/art/2012/ural1099.cpp 没错,这是用来解决URAL 1099 Work

带花树算法学习笔记

笑着哭i 提交于 2019-12-24 02:47:49
带花树算法学习笔记 难得yyb写了一个这么正式的标题 Q:为啥要学带花树这种东西啊? A:因为我太菜了,要多学点东西才能不被吊打 Q:为啥要学带花树这种东西啊? A:因为我做自己的专题做不动了,只能先去“预习”ppl的专题了 Q:为啥要学带花树这种东西啊? A:因为可以用来做题啊,比如某WC题目 先推荐一个很皮很皮的带花树讲解: 戳这里嗷 QaQ 言归正传 带花树的算法用来解决一般图的最大匹配问题 说起来,是不是想起来网络流里面的最小路径覆盖? 或者二分图的最大匹配的问题? 的确,带花树解决一般图的最大匹配问题类似于这些东西。 但是肯定是有不同的。 比方说: 我们用匈牙利的思路来解决一般图 我们是可以很容易就让算法挂掉的 只需要一个奇环就可以啦 (让我偷张图片过来) 看见没有 有了一个奇环,在匹配的时候黑白就会翻转过来。 所以我们当然不能直接用匈牙利来做。 但是,这样的问题当然需要解决, 所以就有了带花树算法。 你可以理解为: 带花树算法=匈牙利算法+处理奇环 因为不打算长篇大论, 我按照带花树的步骤来写写这个算法。 (随时对比匈牙利算法) 匈牙利算法第一步:找到一个未被匹配的点,从这个点开始匹配 带花树算法第一步:找到一个未被匹配的点,从这个点开始匹配 貌似没有区别。。。 接下来匈牙利算法会用 \(dfs\) 来寻找增广路 带花树算法使用 \(bfs\) 将当前点丢进队列里面

lca最近公共祖先(模板)

痴心易碎 提交于 2019-12-21 11:59:34
洛谷上的lca模板题—— 传送门 1.tarjan求lca 学了求lca的 tarjan算法(离线) ,在洛谷上做模板题,结果后三个点超时。 又把询问改成链式前向星,才ok。 这个 博客 ,tarjan分析的很详细。 附代码—— #include <cstdio> #include <cstring> const int maxn = 500001; int n, m, cnt, s, cns; int x, y, z[maxn];//z是x和y的lca int f[maxn], head[maxn], from[maxn]; bool vis[maxn]; struct node { int to, next; }e[2 * maxn]; struct Node { int to, next, num; }q[2 * maxn]; inline int read()//读入优化 { int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; }

【NOIP模拟赛】异象石

家住魔仙堡 提交于 2019-12-19 23:32:06
Description Adera是Microsoft应用商店中的一款解谜游戏。 异象石是进入Adera中异时空的引导物,在Adera的异时空中有一张地图。这张地图上有N个点,有N-1条双向边把它们连通起来。起初地图上没有任何异象石,在接下来的M个时刻中,每个时刻会发生以下三种类型的事件之一: 1.地图的某个点上出现了异象石(已经出现的不会再次出现); 2.地图某个点上的异象石被摧毁(不会摧毁没有异象石的点); 3.向玩家询问使所有异象石所在的点连通的边集的总长度最小是多少。 请你作为玩家回答这些问题。 Input Format 第一行有一个整数N,表示点的个数。 接下来N-1行每行三个整数x,y,z,表示点x和y之间有一条长度为z的双向边。 第N+1行有一个正整数M。 接下来M行每行是一个事件,事件是以下三种格式之一: x 表示点x上出现了异象石 x表示点x上的异象石被摧毁 ?表示询问使当前所有异象石所在的点连通所需的边集的总长度最小是多少。 Output Format 对于每个 ?事件,输出一个整数表示答案。 Sample Input 6 1 2 1 1 3 5 4 1 7 4 5 3 6 4 2 10 + 3 + 1 ? + 6 ? + 5 ? - 6 - 3 ? Sample Output 5 14 17 10 Hint 数据范围与约定 对于30%的数据,1 ≤ n, m 

树上差分

你说的曾经没有我的故事 提交于 2019-12-17 07:08:51
转载于 https://www.luogu.org/blog/sincereactor/shu-shang-ci-fen-di-liang-zhong-sai-lu 例题 先摆一波题 天天爱跑步 ; 运输计划 ; 疫情控制 ; 松鼠的新家 ; 一.关于边的差分(如找被所有路径共同覆盖的边) 首先我们除了一般的grand,depth等数组以外,多开两个数组:tmp和prev。 tmp用来记录点的出现次数(具体点说实际上记录的是点到其父亲的边的出现次数),prev记录每个点到其父亲的那条边。对于一条起点s,终点t的路径。我们这样处理: tmp[s]++,tmp[t]++,tmp[LCA(s,t)]-=2。(记住:最后要从所有叶结点把权值向上累加。)以一次操作为例,我们来看看效果(可以画一张图)。首先tmp[s]++,一直推上去到根,这时候s到root的路径访问次数都+1,tmp[t]++后,t到lca路径加了1,s到lca路径加了1,而lca到根的路径加了2。 这时,我们只需要tmp[LCA(s,t)]-=2,推到根,就能把那些多余的路径减掉,达到想要的目的。而这是一次操作,对于很多次操作的话,我们只需要维护tmp,而不必每次更新到根,维护好tmp最后Dfs一遍即可。这时如果tmp[i]==次数的话,说明i到其父亲的边是被所有路径覆盖的。如图 二.关于点的差分

CTGU_训练实录

 ̄綄美尐妖づ 提交于 2019-12-12 13:42:35
前言 之前做题都没有感觉,慢慢出去比赛后,打Codeforces,看别的人博客,知乎上的讨论,慢慢的对算法有一些自己的思考。特写是最近看知乎上别人说的Dijkstra利用水流去理解,LCA的学习,感觉自己原来还只是浮在表面的感觉,就是没有真的能做到深入思考,快速理解这些。无论什么算法,如果你能通俗易懂的让别人理解这个,才说明你真正理解了,这里面还有很大一段路要走,但是走着走着有些东西感觉比以前清晰了很多。而且我的博客已经很久没更新了,说明真的没有在用心搞,总是想着要怎么去学,不如每周打场比赛,把不会的题目补完,再辅以系统的学习来的实在。 本来打算把这个自己放到印象笔记上的,后来觉得放在博客上督促自己吧,不然总是自以为然觉得自己有在补题,但是又没学什么的感觉 (实际上真的是这样) ,希望把自己平时的训练情况记录下来,之后可能还会单独开一个训练计划的帖子置顶。 实录 2019.12.12 上午9点到工作室还是补CF600的F题,但是明显搞不定,需要学些图论的知识点。 就从LCA入手开始看 , Tarjan有点懂了但是还是没看懂 来源: https://www.cnblogs.com/wizarderror/p/12028167.html