题意:

对于 1 ≤ i ≤ n, 求出点 i 度数强制为 1 的情况下最小生成树的最大边的权值。

题解:
相当于求出删掉每个点之后的MSTMSTMST的最大值。

我们按边的权值从小到大加入新图, 很显然当一个点不是割点的时候这条边就是它对应的答案。

先建出MST,然后动态加边。

我们要维护每个点iii的每个子树j" role="presentation">jjj连到faifaifa_i的最早的时间hjhjh_j,同时要维护子树之间最早的相连边。

第二个直接在lca(x,y)lca(x,y)lca(x,y)处并查集维护,对于第一个,一条边(x,y)(x,y)(x,y)的能更新的hhh的区间是x→lca(x,y)" role="presentation">x→lca(x,y)x→lca(x,y)x \rightarrow lca(x,y), y→lca(x,y)y→lca(x,y)y \rightarrow lca(x,y)。同样并查集维护还没有被更新的点即可。

#include <bits/stdc++.h>
using namespace std;
typedef vector <int> ::iterator it_v;const int RLEN=1<<18|1;
inline char nc() {static char ibuf[RLEN],*ib,*ob;(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));return (ib==ob) ? -1 :*ib++;
}
inline int rd() {char ch=nc(); int i=0,f=1;while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}return i*f;
}
inline void W(int x) {static int buf[50];if(!x) {putchar('0'); return;}if(x<0) {putchar('-'); x=-x;}while(x) {buf[++buf[0]]=x%10; x/=10;}while(buf[0]) {putchar(buf[buf[0]--]+'0');}
}const int N=1e6+50,LIM=20,INF=0x3f3f3f3f;
int n,m,anc[N],up[N],fa[N][LIM],dep[N],mn[N],mnv;
int h[N];
struct E {int x,y,w;}e[N];
vector <int> edge[N];
vector <E> link_son[N];inline int ga(int x) {return (x==anc[x]) ? x : (anc[x]=ga(anc[x]));}
inline int gu(int x) {return (x==up[x]) ? x : (up[x]=gu(up[x]));}inline int jump(int x,int d) {for(int i=0;i<LIM;i++)if(d&(1<<i)) x=fa[x][i];return x;
}
inline int get_lca(int x,int y) {if(dep[x]<dep[y]) swap(x,y);if(dep[x]!=dep[y]) x=jump(x,dep[x]-dep[y]);if(x==y) return x;for(int i=LIM-1;~i;i--) if(fa[x][i]!=fa[y][i])x=fa[x][i], y=fa[y][i];return fa[x][0];
}inline int dfs(int x,int f) {anc[x]=x; up[x]=x; h[x]=INF; dep[x]=dep[f]+1; fa[x][0]=f;for(int i=1;i<LIM;i++) fa[x][i]=fa[fa[x][i-1]][i-1];for(auto v:edge[x]) if(v!=f) dfs(v,x);
}inline int group(int x,int f,int v) {x=gu(x);while(dep[x]>dep[f]+1) {h[x]=min(h[x],v);up[x]=fa[x][0];x=gu(x);}
}inline void link(int x,int y,int t) {int lca=get_lca(x,y);group(x,lca,t);group(y,lca,t);if(x==lca || y==lca) return;x=jump(x,dep[x]-dep[lca]-1);y=jump(y,dep[y]-dep[lca]-1);if(ga(x)!=ga(y)) {anc[anc[x]]=anc[y];link_son[lca].push_back((E){x,y,t});}
}int main() {n=rd(), m=rd();for(int i=1;i<=n;i++) anc[i]=i, mn[i]=INF;for(int i=1;i<=m;i++) {e[i].x=rd(), e[i].y=rd(), e[i].w=rd();mn[e[i].x]=min(mn[e[i].x],e[i].w);mn[e[i].y]=min(mn[e[i].y],e[i].w); }sort(e+1, e+m+1, [&](const E &a,const E &b){return a.w<b.w;});for(int i=1;i<=m;i++) {int x=e[i].x, y=e[i].y;if(ga(x)!=ga(y)) {mnv=e[i].w;anc[anc[x]]=anc[y];edge[x].push_back(y);edge[y].push_back(x);}}for(int i=1;i<=n;i++)if(ga(i)!=ga(1)) {cout<<-n; return 0;}for(int i=1;i<=n;i++) sort(edge[i].begin(), edge[i].end());dfs(1,0);for(int i=1;i<=m;i++) {int x=e[i].x, y=e[i].y;int p=lower_bound(edge[x].begin(),edge[x].end(),y)-edge[x].begin();if(p<edge[x].size() && edge[x][p]==y) continue;link(x,y,i);}long long sum=0;for(int i=1;i<=n;i++) {static E stk[N]; int tl=0,f=(i==1) ? edge[i][0] :fa[i][0];anc[f]=f;for(auto v:edge[i])if(v!=fa[i][0]) stk[++tl]=(E){v,f,h[v]}, anc[v]=v;for(auto v:link_son[i])stk[++tl]=v;sort(stk+1,stk+tl+1,[&](const E &a,const E &b) {return a.w<b.w;});int ans=0;for(int j=1;j<=tl;j++) {int x=stk[j].x, y=stk[j].y;if(ga(x)!=ga(y)) {ans=stk[j].w;anc[anc[x]]=anc[y];}if(ans==INF) break;} sum+= (ans<INF) ? max(e[ans].w,max(mn[i],mnv)): (-1);}cout<<sum;
}

NOI模拟 : Vain (并查集维护割点)相关推荐

  1. 【BZOJ4199】品酒大会,后缀数组+并查集维护

    Time:2016.05.23 Author:xiaoyimi 转载注明出处谢谢 传送门 题面及样例 思路: 求lcp相关问题上有类似于差异的地方,但不完全是,"差异"所求的是lc ...

  2. Ural 1671 - Anansi's Cobweb 倒过来做...并查集维护..

    题意: 给出一个无向图..然后不断的删边..问每次删边后..整个图是由几个联通块组成的.... 题解: 以前做过一个题..是CF上面的...是不断的删边..并询问某两点的最短路..当时的方法是倒过来. ...

  3. F 魏迟燕的自走棋(思维+贪心+并查集维护联通块/左部点配对边<=2的匈牙利)

    https://ac.nowcoder.com/acm/contest/9984/F 参考:F 魏迟燕的自走棋(贪心+并查集) 将每个人看成一个点,武器的能力值抽象成边,这样就转化成图论的模型了. 然 ...

  4. 【uva12232/hdu3461】带权并查集维护异或值

    [uva12232/hdu3461]带权并查集维护异或值 题意: 对于n个数a[0]~a[n-1],但你不知道它们的值,通过逐步提供给你的信息,你的任务是根据这些信息回答问题: I P V :告诉你a ...

  5. JZOJ4708. 【NOIP2016提高A组模拟8.20】奇洛金卡达 倒着做的思想+并查集维护

    题目大意 给定一个长度小于等于kk的字符串和qq,表示现在有qq个操作,每个操作给定两个参数li,ril_i,r_i表示把现在的字符串第lil_i到rir_i把其中编号为奇数的按顺序写下来,再在后面把 ...

  6. 【模板/经典题型】并查集维护生成树

    这里的并查集是按秩合并并查集. 这种方法维护生成树的时候可以维护一个点到根的权值. 但是由于合并的时候做了一个类似换根一样的操作,因此这个权值通常只能是异或之类的. //find-union-set ...

  7. 紫书 习题 11-12 UVa 1665 (并查集维护联通分量)

    这道题要逆向思维 反过来从大到小枚举, 就是在矩阵中一点一点加进去数字,这样比较 好操作, 如果正着做就要一点一点删除数字, 不好做. 我们需要在这个过程中维护联通块的个数, 这里用到了并查集. 首先 ...

  8. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  9. NOI银河英雄传说(并查集)

    问题: 解决: 思路上比较简单,利用并查集 1.合并操作,直接将两个元素所在的树合并,并且将新的树里每个元素到根节点的距离更新 2.查询操作,有两种情况 a.两元素不在同一棵树里,说明距离无法计算,输 ...

最新文章

  1. Java中finally和return执行顺序
  2. html5引入外联样式的优先级,CSS的4种引入方式及优先级
  3. ES6公用分页组件的封装及应用举例
  4. php mysql 星级评分_jQuery+PHP实现星级评分效果
  5. [js高手之路]构造函数的基本特性与优缺点
  6. topcoder srm 305 div1
  7. 字节跳动开发者工具_FAQ | 字节跳动小游游戏发布常见问题汇总
  8. mysql was1067_MySQL启动提示1067错误的解决
  9. SystemCenter2012SP1实践(0)本系列摘要目录
  10. Delphi字符串转日期,强大到窒息,VarToDateTime解决了困扰很久的小问题
  11. over oracle 不足补零,oracle的rank,over partition涵数使用
  12. ES6、7学习笔记(尚硅谷)-5-箭头函数
  13. error LNK2019: 无法解析的外部符号 main,函数 “int __cdecl __scrt_common_main_seh(void)“ (?__scrt_common_main_seh
  14. 通过 Kali Linux 暴力破解 WiFi
  15. eclipse如何修改项目的jdr或jre版本
  16. chrome清除某个网站缓存
  17. 开发手札:git日常抽风记录
  18. JavaScript单选框选择操作
  19. SwiftUI是什么,听听大牛们如何说
  20. 你的老师 每天都在你身边

热门文章

  1. 你想进大厂吗?这份所有大厂都绕不过的MySQL宝典值得你一看
  2. 中国计算机大赛游戏,我校在第10届全国大学生计算机设计大赛第暨4届中国大学生动漫游戏设计大赛,“星雨杯”福建省级赛的表现优异...
  3. 新路由3 稳定强信号eeprom
  4. 二进制与十进制间的转化
  5. 笔记本有没有必要加内存条?
  6. 简练软考知识点整理-规划风险管理
  7. 2<<3是什么意思?
  8. 1.MySQL 常用语句
  9. 2022年5月8日 解决手机连接电脑无法选择“传输文件”
  10. 机器人来了!日本保险巨头启用AI替换30%理赔部员工