JZOJ 4313. 【NOIP2015模拟11.4】电话线铺设
题目
思路
先求只用王牌电缆的最小生成树
再选一条李牌电缆替换王牌电缆
使答案最小就完了
假如要替换的李牌电缆两端点是 \(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();
}
JZOJ 4313. 【NOIP2015模拟11.4】电话线铺设的更多相关文章
- [JZOJ 4307] [NOIP2015模拟11.3晚] 喝喝喝 解题报告
题目链接: http://172.16.0.132/senior/#main/show/4307 题目: 解题报告: 题目询问我们没出现坏对的连续区间个数 我们考虑从左到有枚举右端点$r$,判断$a[ ...
- JZOJ 4298. 【NOIP2015模拟11.2晚】我的天
4298. [NOIP2015模拟11.2晚]我的天 (File IO): input:ohmygod.in output:ohmygod.out Time Limits: 1000 ms Memor ...
- 【NOIP2015模拟11.5】JZOJ8月5日提高组T2 Lucas的数列
[NOIP2015模拟11.5]JZOJ8月5日提高组T2 Lucas的数列 题目 PS:\(n*n*T*T<=10^{18}\)而不是\(10^1*8\) 题解 题意: 给出\(n\)个元素的 ...
- 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃
[NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...
- 【NOIP2015模拟11.2晚】JZOJ8月4日提高组T2 我的天
[NOIP2015模拟11.2晚]JZOJ8月4日提高组T2 我的天 题目 很久很以前,有一个古老的村庄--xiba村,村子里生活着n+1个村民,但由于历届村长恐怖而且黑暗的魔法统治下,村民们各自过着 ...
- 【NOIP2015模拟11.4】JZOJ2020年8月6日提高组T2 最优交换
[NOIP2015模拟11.4]JZOJ2020年8月6日提高组T2 最优交换 题目 题解 题意 有一个长度为\(n\)的正整数 最多可以进行\(k\)次操作 每次操作交换相邻两个位置上的数 问可以得 ...
- 【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划
[NOIP2015模拟11.4]JZOJ8月6日提高组T1 刷题计划 题目 题解 题意 有\(n\)道题,编号为1~\(n\) 给出\(m\)次操作 每次操作有3种类型 1 \(x\) 表示交了\(A ...
- 【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行
[NOIP2015模拟11.5]JZOJ8月5日提高组T3 旅行 题目 若不存在第\(k\)短路径时,输出"Stupid Mike" 题解 题意 给出一个有\(n\)个点的树 问这 ...
- 【NOIP2015模拟11.3】备用钥匙
题目 你知道Just Odd Inventions社吗?这个公司的业务是"只不过是奇妙的发明(Just Odd Inventions)".这里简称为JOI社. JOI社有N名员工, ...
- JZOJ4307. 【NOIP2015模拟11.3晚】喝喝喝
Description
随机推荐
- AI绘画提示词创作指南:DALL·E 2、Midjourney和 Stable Diffusion最全大比拼 ⛵
作者:韩信子@ShowMeAI 深度学习实战系列:https://www.showmeai.tech/tutorials/42 自然语言处理实战系列:https://www.showmeai.tech ...
- 关键字break和continue
关键字:break 和continue提供了另一种控制循环的方式. break 是直接退出循环体 如: continue 是退出当前循环迭代 如: 需要注意的是:使用过多的break和continu ...
- 图书管理系统、聚合函数、分组查询、F与Q查询
目录 图书管理系统 1.表设计 2.首页搭建.展示 书籍的添加 书籍编辑 书籍删除 聚合函数 Max Min Sum Count Avg 分组查询 按照表分组 按照字段分组 F与Q查询 F查询 Q查询 ...
- 基于.NetCore开发博客项目 StarBlog - (25) 图片接口与文件上传
前言 上传文件的接口设计有两种风格,一种是整个项目只设置一个接口用来上传,然后其他需要用到文件的地方,都只存一个引用ID:另一种是每个需要文件的地方单独管理各自的文件.这俩各有优劣吧,本项目中选择的是 ...
- 基于容器的PaaS混合云的几种形式
概述 这是 Gartner 的一个图,提供了全球的基于容器的 PaaS 公有云.混合云服务的梳理展示: 这里提供一个其他的视角: 中国市场,基于容器的 PaaS 混合云(公有云 + 私有云)的相关厂商 ...
- MYSQL进阶学习笔记
MySQL在Linux中的使用: 1.查看mysql在linux的安装版本 mysqladmin –version 2.mysql服务的启动与停止 (1).启动: service mysql star ...
- 一站式云原生体验|龙蜥云原生ACNS + Rainbond
关于 ACNS 龙蜥云原生套件 OpenAnolis Cloud Native Suite(ACNS)是由龙蜥社区云原生 SIG 推出的基于 Kubernetes 发行版本为基础而集成的套件能力,可以 ...
- C++ 编译依赖管理系统分析以及 srcdep 介绍
C++ 编译依赖管理系统分析以及 srcdep 介绍 如果用 C++ 写一个中小型软件,有要用到很多第三方库的话,相信不少人会觉得比较麻烦.很多新兴的语言都有了统一的依赖管理系统和构建系统,但是 C/ ...
- 【大型软件开发】浅谈大型Qt软件开发(一)开发前的准备——在着手开发之前,我们要做些什么?
前言 最近我们项目部的核心产品正在进行重构,然后又是年底了,除了开发工作之外项目并不紧急,加上加班时间混不够了....所以就忙里偷闲把整个项目的开发思路聊一下,以供参考. 鉴于接下来的一年我要操刀这个 ...
- iOS开发小结 - 通过PUT请求上传数据
一般服务器上传数据一般都是用POST请求,这样通过AFNetworking的POST请求稳稳的,但是有一天遇到一个问题,服务器上传数据用的是PUT请求,发现用AFNetworking并不是那么好用,今 ...