题目

思路

先求只用王牌电缆的最小生成树

再选一条李牌电缆替换王牌电缆

使答案最小就完了

假如要替换的李牌电缆两端点是 \(u,v\)

那么生成树中 \(u \Longrightarrow lca(u,v)\) 和 \(v \Longrightarrow lca(u,v)\) 这两条链中的权值最大的边就是要替换的边

类似于次小生成树

倍增维护就好了

注意,有可能只用王牌电缆无法构成最小生成树

这里特判一下,此时跑最小生成树最终的结果必然是两个不连通的集合

这使枚举的李牌电缆就要使它们联通,求一个最小的李牌电缆即可

#include<cstdio>
#include<algorithm>
using namespace std; const int N = 2e5 + 5;
int n , W , L , h[N] , fa[N] , tot , vis[N] , size[N] , lw , lid , hl;
int f[N][20] , anc[N][20] , ind[N][20] , dep[N] , ans , s , rt; struct edge{
int nxt , to , w , id;
}e[N << 1]; struct Edge{
int u , v , w , id;
}E[N]; struct Edge1{
int u , v , w;
}l[N]; inline void addedge(int u , int v , int w , int id)
{
e[++tot] = (edge){h[u] , v , w , id};
h[u] = tot;
} inline bool cmpE(Edge x , Edge y){return x.w < y.w;}
inline int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);} inline bool merge(int x , int y)
{
int xx = find(x) , yy = find(y);
if (fa[xx] != fa[yy])
{
if (size[xx] < size[yy]) fa[xx] = fa[yy] , size[yy] += size[xx];
else fa[yy] = fa[xx] , size[xx] += size[yy];
return 1;
}
return 0;
} inline void Kruskal()
{
int u , v , w;
for(register int i = 1; i <= W; i++)
scanf("%d%d%d" , &E[i].u , &E[i].v , &E[i].w) , E[i].id = i;
sort(E + 1 , E + W + 1 , cmpE);
for(register int i = 1; i <= n; i++) fa[i] = i , size[i] = 1;
for(register int i = 1; i <= W; i++)
{
if (merge(E[i].u , E[i].v))
{
ans += E[i].w , s++;
vis[E[i].id] = 1;
addedge(E[i].u , E[i].v , E[i].w , E[i].id);
addedge(E[i].v , E[i].u , E[i].w , E[i].id);
if (!rt) rt = E[i].u;
}
if (s == n - 1) break;
}
} inline void dfs(int x , int father)
{
for(register int i = 1; i <= 17; i++)
if (f[x][i - 1])
{
f[x][i] = f[f[x][i - 1]][i - 1];
if (anc[x][i - 1] < anc[f[x][i - 1]][i - 1])
anc[x][i] = anc[f[x][i - 1]][i - 1] , ind[x][i] = ind[f[x][i - 1]][i - 1];
else anc[x][i] = anc[x][i - 1] , ind[x][i] = ind[x][i - 1];
}
else break; for(register int i = h[x]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == father) continue;
f[v][0] = x , dep[v] = dep[x] + 1 , anc[v][0] = e[i].w , ind[v][0] = e[i].id;
dfs(v , x);
}
} inline void update(int ll , int u , int v)
{
if (dep[u] < dep[v]) swap(u , v);
int deep = dep[u] - dep[v] , sum;
int t = -0x3f3f3f3f , id;
for(register int i = 0; i <= 17; i++)
if (deep & (1 << i))
{
if (t < anc[u][i]) t = anc[u][i] , id = ind[u][i];
u = f[u][i];
}
if (u == v)
{
sum = ans - t + l[ll].w;
if (sum < lw) lw = sum , lid = ll , hl = id;
return;
}
for(register int i = 17; i >= 0; i--)
if (f[u][i] != f[v][i])
{
if (t < anc[u][i]) t = anc[u][i] , id = ind[u][i];
if (t < anc[v][i]) t = anc[v][i] , id = ind[v][i];
u = f[u][i] , v = f[v][i];
}
if (t < anc[u][0]) t = anc[u][0] , id = ind[u][0];
if (t < anc[v][0]) t = anc[v][0] , id = ind[v][0]; sum = ans - t + l[ll].w;
if (sum < lw) lw = sum , lid = ll , hl = id;
} inline void getans()
{
for(register int i = 1; i <= L; i++) scanf("%d%d%d" , &l[i].u , &l[i].v , &l[i].w);
if (s != n - 1)
{
int Min = 0x3f3f3f3f , ld = 0;
for(register int i = 1; i <= L; i++)
if (find(l[i].u) != find(l[i].v) && l[i].w < Min)
Min = l[i].w , ld = i;
printf("%d\n" , ans + Min);
for(register int i = 1; i <= W; i++)
if (vis[i]) printf("%d\n" , i);
printf("%d\n" , ld);
return;
}
dfs(rt , 0);
lw = 0x3f3f3f3f;
for(register int i = 1; i <= L; i++) update(i , l[i].u , l[i].v);
printf("%d\n" , lw) , vis[hl] = 0;
for(register int i = 1; i <= W; i++)
if (vis[i]) printf("%d\n" , i);
printf("%d\n" , lid);
} int main()
{
freopen("telephone.in" , "r" , stdin);
freopen("telephone.out" , "w" , stdout);
scanf("%d%d%d" , &n , &W , &L);
Kruskal();
getans();
}

最新文章

  1. MVC WebAPI中响应客户端请求返回图片
  2. WebAPI IIS PUT和DELETE请求失败
  3. &lt;读书笔记&gt;软件调试之道 :从大局看调试-零容忍策略
  4. [转]使用URLDecoder和URLEncoder对中文进行处理
  5. js-延迟处理函数
  6. codeforces round #234B(DIV2) A Inna and Choose Options
  7. 使用uploadify上传控件无法进入后台问题分析
  8. Java原来如此-比较器(Comparable、Comparator)
  9. python 之 range()
  10. [转载]Badboy使用教程
  11. [小技巧]让你的GridView支持IQueryable,并自动实现真分页
  12. Mac 在命令行快速切换目录 mark
  13. C++第11周(春)项目2 - 职员有薪水了
  14. KEIL MDK环境下uCOS-II在LPC17xx上的移植实例
  15. VMware workstation批量创建虚拟机和自动化安装操作系统(一)
  16. linux下boost的安装与编译
  17. 单台PC玩转NEUTRON(一:环境准备)
  18. 2018-2019-2 20165325 网络对抗技术 Exp4 恶意代码分析
  19. ADO.NET五大对象详解
  20. [BZOJ1814]Formula 1

热门文章

  1. 2022年鲜为人知的CSS 特性了解起来~
  2. 【大数据课程】高途课程实践-Day01:Python编写Map Reduce函数实现各商品销售量展示(类似wordcount)
  3. 【每日一题】【直接循环&amp;二分查找】2022年2月10日-NC32 求平方根
  4. K8s架构|全面整理K8s的架构介绍
  5. AIBOX视频边缘计算终端,助力识别人员违规行为!
  6. Hadoop如何保证自己的江湖地位?Yarn功不可没
  7. Spring 6 源码编译和高效阅读源码技巧分享
  8. Qt多线程开发总览,既然用到了就记录一下
  9. pyCharm中下载包的速度慢的解决方案
  10. 万字长文解析Scaled YOLOv4模型(YOLO变体模型)