模板:环套树

文章目录

  • 前言
  • 解析
    • 找环
      • 代码
  • 练习
  • 环套树的直径
    • 代码
  • thanks for reading!

前言

环套树者,一个环套一棵树也

解析

定义:n个点,n条边的无向连通图
其实就是树多了一条边,连出了一个环

性质:如果对环套树进行dfs,多出的一条非树边一定是一条返祖边

考虑dfs的过程如果它不是返祖边,dfs的时候就会直接从这条边过去,该边就会成为树边了

找环

如何在环套树上找到非树边?
考虑dfs,如果出边指向已经被搜过的点,那么这条边(和它的反向边)就是非树边
注意!:这里dfs的时候不能传来到当前节点的节点fa,而是要传来到这个条的边,否则在n=2的时候会找不到非树边

代码

void find_circle(int x,int pre){vis[x]=1;for(int i=fi[x];~i;i=p[i].nxt){if(i==(pre^1)) continue;int to=p[i].to;if(vis[to]){e=i;u=x;v=to;continue;}find_circle(to,i);}
} 

练习

城市环路
骑士
两道很接近的较水的题
解决环套树后就变成没有上司的舞会了

环套树的直径

找出环上的所有点
首先考虑不经过环的路径对每个点跑一遍树形dp,求出每个点不包含环上的点的子树的直径
答案首先可以对这些直径取ma尝试作为答案
下面考虑经过环的路径
刚才dp时可以顺便求出连在每个环上点上的最长链len
那么经过环的最长路径就可以表示为:
leni+lenj+dist(i,j)len_i+len_j+dist(i,j)leni+lenj+dist(i,j)
考虑求上面的最大值,可以破环成链,倍长后用单调队列优化解决

代码

(本题调来调去,代码有些屎山)

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100;
#define ll long long
#define I register int
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
} 
int n;
struct node{int to,nxt,v;
}p[N<<1];
int fi[N],cnt=-1;
void addline(int x,int y,int v){p[++cnt]=(node){y,fi[x],v};fi[x]=cnt;
}
ll ans;
int u,v,fa[N],fv[N];
bool vis[N];
int id[N],E=-1;
void find_circle(int x,int pre){//printf("x=%d fa=%d\n",x,fa[x]);vis[x]=1;for(int i=fi[x];~i;i=p[i].nxt){if(i==(pre^1)) continue;if(i==E||i==(E^1)) continue;int to=p[i].to;if(vis[to]){E=i;u=x;v=to;continue;}fa[to]=x;fv[to]=p[i].v;find_circle(to,i);}
}
ll dis[N],d[N];
void dfs(int x,int f){ll mx=0,sec=0;d[x]=0;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f||id[to]){//printf("  fail:x=%d to=%d\n",x,to);continue;}dfs(to,x);ll now=dis[to]+p[i].v;//printf("  x=%d to=%d now=%lld\n",x,to,now);if(now>mx) swap(now,mx);if(now>sec) swap(now,sec);d[x]=max(d[x],d[to]);}//printf("x=%d mx=%lld sec=%lld\n",x,mx,sec);dis[x]=mx;d[x]=max(d[x],mx+sec);
}
int q[N],st,ed,len;
ll sum[N<<1];
ll val(int x,int now){now--;
//	printf("val:x=%d now=%d id=%d res=%lld\n",x,now,id[x],dis[x]+max(sum[now]-sum[id[x]-1],sum[len]-(sum[now])+sum[id[x]-1]));return dis[x]+max(sum[now]-sum[id[x]-1],sum[len]-(sum[now])+sum[id[x]-1]);
}
ll a[N<<1],dd[N<<1];
void solve(int x){find_circle(x,-2);int uu=u;len=1;id[uu]=1;while(uu!=v){len++;uu=fa[uu];id[uu]=len;}uu=u;ll res=0;dfs(u,0);res=max(res,d[u]);while(uu!=v){uu=fa[uu];dfs(uu,0);res=max(res,d[uu]);}for(uu=u;1;uu=fa[uu]){//printf("u=%d dis=%lld d=%lld\n",uu,dis[uu],d[uu]);if(uu==v) break;}for(uu=u;uu!=v;uu=fa[uu]){a[id[uu]]=fv[uu];dd[id[uu]]=dis[uu];sum[id[uu]]=sum[id[uu]-1]+fv[uu];}a[len]=p[E].v;sum[len]=sum[len-1]+p[E].v;dd[len]=dis[v];for(int i=len+1;i<=2*len;i++){a[i]=a[i-len];dd[i]=dd[i-len];sum[i]=sum[i-1]+a[i];}//for(int i=1;i<=2*len;i++) printf("i=%d a=%lld sum=%lld dd=%lld\n",i,a[i],sum[i],dd[i]);st=1,ed=1;q[1]=1;for(int i=2;i<=2*len;i++){//printf("i=%d len=%d",i,len);while(st<=ed&&i-q[st]>=len) st++;//printf("  i=%d st=%d res=%lld+%lld+%lld-%lld\n",i,q[st],dd[q[st]],dd[i],sum[i],sum[q[st]]);res=max(res,dd[q[st]]+dd[i]+sum[i-1]-sum[q[st]-1]);while(st<=ed&&dd[q[ed]]-sum[q[ed]-1]<=dd[i]-sum[i-1]) ed--;q[++ed]=i;}ans+=res;
//	printf("x=%d res=%lld\n\n",x,res);
}
int main(){memset(fi,-1,sizeof(fi));n=read();for(int i=1;i<=n;i++){int x=read(),y=read();addline(i,x,y);addline(x,i,y);}for(int i=1;i<=n;i++){if(!vis[i]){solve(i);}}printf("%lld",ans);
}
/*
5
2 1
3 3
1 2
2 5
2 4
*/

thanks for reading!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318137.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用PerfView监测.NET程序性能(四):折叠,过滤和时间范围选择

在上一篇文章使用PerfView监测.NET程序性能&#xff08;三&#xff09;&#xff1a;分组中&#xff0c;我们使用了Perfview的分组功能。分组功能旨在对某些函数按照某个格式进行分组&#xff0c;以减少视图中的各种无关函数的数量。但仅有分组还不够&#xff0c;有时我们想将一…

P1352 没有上司的舞会

P1352 没有上司的舞会 题意&#xff1a; 给你一个树&#xff0c;每个点都有权值&#xff0c;选择一些点使得权值和最大&#xff0c;要求父亲节点和子节点不能同时选择 题解&#xff1a; 经典树形dp dp[x][0]表示以x为根的子树&#xff0c;且x不参加舞会的最大快乐值 dp[x][…

基础字符串

初三巨佬djwj233 基础字符串

CF536C-Tavas and Pashmaks【凸壳】

正题 题目链接:https://codeforces.com/contest/536/problem/C 题目大意 nnn个人&#xff0c;第iii个人的游泳速度sis_isi​&#xff0c;跑步速度是rir_iri​。如果跑道长度是RRR&#xff0c;泳道长度是SSS那么一个人的用时就是RriSsi\frac{R}{r_i}\frac{S}{s_i}ri​R​si​S​…

带旋treap概念及模板,带例题:普通平衡树

带旋Treap二叉查找树BST(Binary Search Tree)定义Treap定义模板合集&#xff08;均为O(logn)O(logn)O(logn)&#xff09;push_up模板旋转模板插入模板删除模板查找前驱模板查找后驱模板查找键值key模板查找节点的修正值rank模板PS&#xff1a;rd的比较问题例题&#xff1a;普通…

微服务系列实践 .NET CORE

从事这个行业转眼已经6年了&#xff0c;从当初刚毕业的在北京朝八晚十&#xff0c;从二环到五环&#xff0c;仍每天精力充沛的小愤青&#xff1b;再到深圳一点一滴的辛勤在软件行业的耕种&#xff0c;从当初单体应用架构到现在微服务架构的经历&#xff0c;回想起来自己的收获倒…

P2607 [ZJOI2008]骑士

P2607 [ZJOI2008]骑士 题意&#xff1a; n个点n个边&#xff0c;每个点都有权值&#xff0c;相邻的点不能同时选择&#xff0c;问如何选择能使得权值最大 题解&#xff1a; 这个题很有P1352 没有上司的舞会这个题的感觉&#xff0c;唯一的区别是那个题保证是树&#xff0c;…

模板:线段树优化建图

前言 百川到海&#xff0c;天下归一 解析 线段树优化建图是用于对一个区间的点连边时的优化方法 建一棵in树一棵出树分别往上和下指即可 大概长这样 &#xff08;pia的洛谷的照片&#xff09; 建树 正常动态开点即可 void build(int &k,int l,int r){tr[ktot](tree){0…

Binary Search

01 分数划分 什么 01 分数划分&#xff0c;叫 Binary Search 多好。 P1642 规划 可以二分答案 \(x\)&#xff0c;考虑选择 \(n-m\) 个数使得答案 \(\ge x\)。 \[\dfrac{\sum w(i)}{\sum c(i)}\ge x \]\[\sum w(i)\ge \sum (x\times c(i)) \]\[\sum(w(i)-x\times c(i))\ge 0 \]之…

CF1556F-Sports Betting【状压dp,数学期望】

正题 题目链接:https://www.luogu.com.cn/problem/CF1556F 题目大意 nnn个点的一张竞赛图&#xff0c;每个点有一个权值aia_iai​&#xff0c;(i,j)(i,j)(i,j)之间的边iii连jjj的概率是aiaiaj\frac{a_i}{a_ia_j}ai​aj​ai​​&#xff0c;否则jjj连iii。 现在期望有多少个点…

[非旋平衡树]fhq_treap概念及模板,例题:普通平衡树,文艺线段树

文章目录概念全套模板push_up模板split拆树模板(按权值拆)split拆树模板(按个数拆)merge合并模板&#xff08;地址版&#xff09;merge合并模板&#xff08;带返回根&#xff09;区间模板insert插入模板delete删除模板find_kth找第k大模板get_rank找排名模板pre找前驱模板suf找…

P4381 [IOI2008]Island

P4381 [IOI2008]Island 题意&#xff1a; 给你一棵基环树森林&#xff0c;求出基环树的直径之和. 题解&#xff1a; 对于基环树,我们将环看作根,那么直径有两种情况:: 1.不经过环,也就是环上某个点的子树内部,对于这种情况,直接在子树内部处理直径,更新答案即可; 2.经过环…

20210912模拟

文章目录总结复盘总结 190pts 50403070 今天吸取了昨天的教训&#xff0c;没有再像之前一样先死磕一道题&#xff0c;把命运押在切题上&#xff0c;整体时间分配还算合理 要认真审题&#xff01; 今天T1少看了条件&#xff0c;T4一开始看错题意浪费了时间… 复盘 先看题 乍…

surging 微服务引擎 1.0 正式发布

surging 是一个分布式微服务引擎,提供高性能RPC远程服务调用&#xff0c;服务引擎支持http、TCP、WS、Mqtt协议,采用Zookeeper、Consul作为surging服务的注册中心&#xff0c;集成了哈希一致性&#xff0c;随机&#xff0c;轮询、压力最小优先作为负载均衡的算法&#xff0c;底…

CF1594F-Ideal Farm【构造】

正题 题目链接:https://www.luogu.com.cn/problem/CF1594F 题目大意 给出n,s,kn,s,kn,s,k&#xff0c;求是否所有的长度为nnn且和为sss的正整数序列都有一段和为kkk的区间。 1≤T≤105,1≤n,s,k≤10181\leq T\leq 10^5,1\leq n,s,k\leq 10^{18}1≤T≤105,1≤n,s,k≤1018 解题…

P4178 Tree

P4178 Tree 题意&#xff1a; 给定一棵 n 个节点的树&#xff0c;每条边有边权&#xff0c;求出树上两点距离小于等于 k 的点对数量。 题解&#xff1a; 点分治的模板题是求等于K的路径条数 本题是求小于等于K的路径条数&#xff0c;我们只需要改变统计答案即可 原本统计答…

YBTOJ:彩色圆环

文章目录前言题目描述InputOutputSample InputSample Output解析代码前言 尽信书&#xff0c;则不如无书 题目描述 Input 仅有一行&#xff0c;该行给出依次两个正整数N, M&#xff0c;分别表示宝石的个数和宝石在变化时可能变成的颜色种类数。 Output 应仅有一行&#xff0…

【2019CSP-J 普及组题解】数字游戏(number),公交换乘(transfer),纪念品(souvenir),加工领奖(work) CSP普及游记

文章目录T1&#xff1a;数字游戏题目CODET2&#xff1a;公交换乘题目CODET3&#xff1a;纪念品题目题解CODET4&#xff1a;加工领奖题目题解CODE关于普及组的想法&游记T1&#xff1a;数字游戏 题目 小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏&…

搭建基于Docker社区版的Kubernetes本地集群

Kubernetes的本地集群搭建是一件颇费苦心的活&#xff0c;网上有各种参考资源&#xff0c;由于版本和容器的不断发展&#xff0c;搭建的方式也是各不相同&#xff0c;这里基于Docker CE的18.09.0版本&#xff0c;在Mac OS、Win10下分别搭建了一次。一、Mac OS下搭建安装Docker …

【做题记录】统计区间(哈希/扫描线)

交题链接 给你一个长度为 \(n(n\le 10^6)\) 的序列&#xff0c;其中每个元素都在 \([1,n]\) 范围中。 询问有多少个区间满足区间中的元素都恰好出现 \(2\) 次。 \(\texttt{solution}~\texttt{1:}\) 哈希 我们考虑如果元素个数 \(\le 64\) 时我们怎么做&#xff1a; 给每个元素分…