题目链接 如果k==1, 显然就是直径. k==2的时候, 把直径的边权变为-1, 然后在求一次直径. 变为-1是因为如果在走一次这条边, 答案会增加1. 学到了新的求直径的方法... #include <bits/stdc++.h> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<…
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=1912 题解: 首先,显然当不加边的时候,遍历一棵树每条边都要经过两次.那么现在考虑k==1的情况,考虑加入的这一条边有什么作用. 显然,如图4边的作用就是使得原来的1-2-3-3-2-1路线变为了4-3-2-1或1-2-3-4,那么作用就是以多走一步的代价使得这条新边两端的两个结点的遍历路径长度减半. 因此,想要使路径最短,就要使这条新边两端的两个结点之间的距离更长,显然,当两端的结点在…
我是智障系列.用了及其麻烦的方法= =其实树形sp就能解决 设直径长度+1为len(环长) 首先k=1,直接连直径两端就好,答案是2*n-len 然后对于k=2,正常人的做法是树形dp:先求直径,然后把树的直径上的所有边权标为-1,再求一次直径设新直径+1为len2,答案是2*(n−1)−len−len2. 然后zz的做法是分两种情况: len=n,直接输出n+1(因为要加个自环) 否则,答案可能从两种情况产生: 新选出的链两端在都原直径环某一个节点下面,这样的情况可以直接求这个节点子树的直径+…
呵呵呵呵呵呵,自己画图,大概半个小时,觉的连上边会成环(是不是该交仙人掌了??)然后求环不重合部分最大就好了, 结果写了一坨DP,最后写不下去了,再次扒了题解. 发现我真的是个sb. k==1,直接是直径 k==2,搞出直径然后把直径删掉(把权值赋为-1,再找直径)(有点像我一开始想的每次找个最长链去贪心,然而,,总觉得,这种题贪心这么可能对) /*#include <bits/stdc++.h> #define LL long long #define lowbit(x) x&(-x…
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1034  Solved: 562[Submit][Status][Discuss] Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离.…
题目 传送门:QWQ 分析 $ k=1 $ 时显然就是树的直径 $ k=2 $ 时怎么做呢? 做法是把一开始树的直径上的边的边权改成$ -1 $,那么当我们第二次用这些边做环时就抵消了一开始的贡献. 所以答案就是边的数量*2 - 一开始树的直径 - 后来树的直径 P.S. 第二次求树的直径时只能dp 代码 #include <bits/stdc++.h> using namespace std; ; int n,dis[maxn], inq[maxn] ; struct Edge{ int u…
1912: [Apio2010]patrol 巡逻 Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离. Sample Input 8 1 1 2 3 1 3 4 5 3 7 5 8 5 5 6 Sample Output 11 HINT 10%的数据中,n ≤ 1000, K = 1: 30%的数据中,K…
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2541  Solved: 1288[Submit][Status][Discuss] Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离.…
[BZOJ1912][Apio2010]patrol 巡逻 Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离. Sample Input 8 1 1 2 3 1 3 4 5 3 7 5 8 5 5 6 Sample Output 11 HINT 10%的数据中,n ≤ 1000,…
http://www.lydsy.com/JudgeOnline/problem.php?id=1912 (题目链接) 题意 给出一棵树,要求在树上添加K(1 or 2)条边,添加的边必须经过一次,使得从1号节点到达每个节点最后返回1号节点所经过的路径最短. Solution 如果不添加边,那么答案一定是每条边经过两次. 如果K为1,那么答案就很明显对吧,找到树的直径,链接直径两端点,使得直径上的边只经过一次,答案最优. 那么如果K为2,我们会发现,当两个环有变重叠时,重叠的边同样是要经过2次.…
Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离. Sample Input 8 1 1 2 3 1 3 4 5 3 7 5 8 5 5 6 Sample Output 11 HINT 10%的数据中,n ≤ 1000, K = 1: 30%的数据中,K = 1: 80%的数据中,…
这道题讨论了好久,一直想不明白,如果按传统的随便某一个点出发找最长链,再回头,K=2 的时候赋了-1就没法用这种方法找最长链了,于是乎,更强的找最长链的方法就来了..类似于DP的东西吧.先上代码: ; type node=record f,t,l:longint; end; var n,k,i,j,ans,num,f,t,diameter,s,sum:longint; b:array[..*maxn] of node; head,go1,go2:array[..maxn] of longint;…
Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的行业是消防业.由于政府对国民的热情忍无可忍(大量的消防经费开销)可是却又无可奈何(总统竞选的国民支持率),所以只能想尽方法提高消防能力. 现在这个国家的经费足以在一条边长度和不超过s的路径(两端都是城市)上建立消防枢纽,为了尽量提高枢纽的利用率,要求其他所有城市到这条路径的距离的最大值最小. 你受…
传送门 一道挺妙的题啊. 对于K==1K==1K==1的直接求树的直径. 对于K==2K==2K==2的先求一次直径,然后考虑到如果两条边加进去形成的两个环重叠就会有负的贡献. 因此把之前那条直径上的边权改成-1再求一次直径就可以了. 代码: #include<bits/stdc++.h> using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar();…
富有思维性的树形dp Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离. Sample Input 8 1 1 2 3 1 3 4 5 3 7 5 8 5 5 6 Sample Output 11 HINT 10%的数据中,n ≤ 1000, K = 1: 30%的数据中,K =…
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小…
题意:从树上任找三点u,v,w.使得dis(u,v)+min(dis(u,w),dis(v,w))最大. 有一个结论u,v必是树上直径的两端点. 剩下的枚举w就行了. 具体不会证... # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include…
树形DP 说是树形DP,其实就是求树的最长链嘛…… K=1的时候明显是将树的最长链的两端连起来最优. 但是K=2的时候怎么搞? 考虑第一次找完树的最长链以后的影响:第一次找过的边如果第二次再走,对答案的贡献会变成-1,因为两次都选这一段的话,反而会使得这一段不得不走两次(如果只被选一次的话就可以只走一次),所以就将第一次找出的树的最长链上的边权值都改为-1.这个操作可以用链表实现(类比一下最小费用最大流的spfa实现!) 题解:http://blog.csdn.net/qpswwww/artic…
Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Output 输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离. Sample Input 8 1 1 2 3 1 3 4 5 3 7 5 8 5 5 6 Sample Output 11 HINT 10%的数据中,n ≤ 1000, K = 1: 30%的数据中,K = 1: 80%的数据中,…
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1912 Algorithm: K=0:res=(n-1)*2   每条边恰好走2遍 K=1:res=res-树上最长链+1 由于每形成环,环上的边对答案的贡献都会-1,因此只要将树上最长链连成环即可 K=2:res=res-树上当前最长链+1 将原树上直径的边的边权赋为-1,表示如果原直径边同时出现在第2个环时对答案贡献增加1(变为2) 证明:第二次求最长链相当于对第一次的“反悔”操作,…
Description 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任一个村庄.每条道路的长度均为 1 个单位. 为保证该地区的安全,巡警车每天要到所有的道路上巡逻.警察局设在编号 为 1 的村庄里,每天巡警车总是从警察局出发,最终又回到警察局. 下图表示一个有 8 个村庄的地区,其中村庄用圆表示(其中村庄 1 用黑色的 圆表示),道路是连接这些圆的线段.为了遍历所有的…
题目链接 容易发现,当加一条边时,树上会形成一个环,这个环上的每个点都是只要走一次的,也就是说我们的答案减少了这个环上点的个数,要使答案最小,即要使环上的点最多,求出直径\(L\),则答案为\(2(n-1)-L+1\). 当加两条边时,同样会形成一个新环,但这个新环可能和第一个环有交点,而这些交点仍是要走两次的,所以我们要让交点的个数尽可能小,所以,把原直径上的所有边权取反,代表若取了这条边,答案会增大那么多,然后再求一次树的直径\(L_1\),则答案为\(2(n-1)-L+1-L_1+1=2n…
题目传送门 我们先来介绍一个概念:树的直径. 树的直径:树中最远的两个节点间的距离.(树的最长链)树的直径有两种方法,都是$O(N)$. 第一种:两遍bfs/dfs(这里写的是两遍bfs) 从任意一个节点出发,遍历一遍树找到与出发点距离最远的点p. 再从节点p出发,遍历一遍求出与p距离最远的点q.则pq即为直径(其中一个) 但是不能处理负权边. int bfs(int x) { queue<int>q; memset(d,0x3f,sizeof(d)); memset(pre,,sizeof(…
如果考虑不算上新修的道路,那么答案显然为\(2*(n-1)\). 考虑\(k=1\)的情况,会发现如果我们新修建一个道路,那么就会有一段路程少走一遍.这时选择连接树的直径的两个端点显然是最优的. 难就难在\(k=2\)的时候,还是上面的思路,首先肯定连接两个叶子结点最优.假设我们连接的是\(x,y\)两个叶子结点,它们到直径的距离分别为\(dis[x],dis[y]\),并设直径上两点的距离为\(d[u,v]\),这里\(u,v\)分别为叶子结点所在链和直径的交点. 因此最后的答案会增加\(d[…
题目链接: https://www.luogu.org/problemnew/show/P3629 分析 最近被众多dalao暴虐,这道题傻逼地调了两天才知道错哪 不过这题比较良心给你一个容易发现性质的图 不修路时 每条路走两次可知需要走\(2(N-1)\)步 \(K=1\) 送分给你,直接\(O(N)\)求直径,若直径长为\(L\),由于新加路还要走一步,少走了\(L-1\)步 \(K=2\) 如果还是用求直径的方法来求发现不太对,与原来直径重叠那部分又要多走一遍 ,于是不妨把原来直径边权取反…
SDOI2011的Dayx第2题 题意: 在树中找到一条权值和不超过S的链(为什么是链呢,因为题目中提到“使得路径的两端都是城市”,如果不是链那不就不止两端了吗——怎么这么机智的感觉...),使得不在链上的点与这条链的距离最大值最小. SOL: 最大值最小!这不是二分的节奏么?然而hzw学长说二分更直观我却一点都没有体会到... 这道题的关键是猜想(貌似还挺好想)并证明(貌似一直都是可有可无的东西,不过还挺好证的),路径一定在直径上,那么我们先两遍*FS找到直径,用一个队列维护链上的路径,以及预…
树的直径 这题如果k=1很简单,就是在树的最长链上加个环,这样就最大化的减少重复的路程 但是k=2的时候需要考虑两个环的重叠部分,如果没有重叠部分,则和k=1的情况是一样的,但是假如有重叠部分,我们可以先把树直径找出来(最长链),然后把路径上的边权全部取反(1变-1),再找一次树的直径,如果第二次找的直径包含了取反的部分(即为重叠部分),这个重叠部分显然需要走两次. 可以推得答案为:2(n-1)-(L1-1)-(L2-1) 如果没有重叠部分,那么显然正确:假如有重叠部分,我们先减去了(L1-1)…
题目 传送门:QWQ 分析 在任意两个不相邻的点连一条线,求这条线能穿过几个三角形. 建图比较讲究(详见代码) 求树的直径. 代码 #include <bits/stdc++.h> using namespace std; ; struct Node{ int x,y,id; }E[maxn]; int cmp(Node a,Node b){ return a.x<b.x||(a.x==b.x&&a.y<b.y); } struct Edge{ int u,v,di…
农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向道路,用各种各样的方法连接这些草地.而且从每片草地出发都可以抵达其他所有草地.也就是说,这些草地和道路构成了一种叫做树的图.输入包含一个详细的草地的集合,详细说明了每个草地的父节点P_i (0 <= P_i <= N).根节点的P_i == 0, 表示它没有父节点.因为奶牛建立了1到K一共K (1 <= K <= N/2)个政党.每只奶牛都要加入某一个政…
题目大意:给出一棵树.求两点间的最长距离. 思路:裸地树的直径.两次BFS,第一次随便找一个点宽搜.然后用上次宽搜时最远的点在宽搜.得到的最长距离就是树的直径. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 80010 using namespace std; int…