CF125E MST company (凸优化+MST)
qwq自闭的一个题
我来修锅辣!!!!!!
这篇题解!可以\(hack\)全网大部分的做法!!!
首先,我们可以把原图中的边,分成两类,一类是与\(1\)相连,另一类是不与\(1\)相连。
原题就转化成选择\(k\)条关键边的\(MST\)
那么我们可以按照tree I 那个题的思路来考虑这个题。
由于是\(MST\),所以函数满足下凸,那么对于这种恰好选\(k\)个的问题,我们可以直接凸优化。
\(erf\)一个值,然后把所有与1相连的边都加上这个值。
对于相等权值的来说,我们优先把不与1相连的边排在前面。
那么这种情况我们二分出来的那个\(mid\)
满足两个条件
1.满足下界,也就是说,能选到<=k条边的最大的\(mid\)
2.在这种情况下,\(mst\)上面的与1相连的边,是“必须出现在MST”上的边。
那么我们考虑该怎么统计方案。
首先,对于那些一定要出现在\(MST\)上的关键边,我们先把他们加入\(ans\)(只加入与1相连的边),然后对于剩下的边,把与1相连的边加上\(mid\)后,进行\(MST\),如果已经选够了\(k\)条边,那么对于剩下的关键边就直接跳过。
这样做正确的原因是,我们首先把必须要出现暗在\(MST\)上的边加入了\(ans\),然后对于剩下的边,只会分成两种,可能在MST上,或者是不可能在MST上,那剩下的部分直接用贪心的思路来做\(MST\)就是没错的。
而网上大多数题解是错的,qwq
所以这个问题困扰了我很久
#include<bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define ll long long
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 3e5+1e2;
struct Edge{
int u,v;
ll w;
int tag,num;
};
Edge e[maxn];
int fa[maxn];
int n,m,k;
int val;
int find(int x)
{
if (fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
bool cmp(Edge a,Edge b)
{
if(a.w==b.w) return a.tag>b.tag;
return a.w<b.w;
}
bool cmp1(Edge a,Edge b)
{
if (a.w==b.w) return a.tag<b.tag;
return a.w<b.w;
}
int solve()
{
for (int i=1;i<=n;i++) fa[i]=i;
sort(e+1,e+1+m,cmp1);
int tot=0;
for (int i=1;i<=m;i++)
{
int f1 = find(e[i].u);
int f2 = find(e[i].v);
if (f1==f2) continue;
fa[f1]=fa[f2];
tot+=e[i].tag;
}
return tot;
}
vector<int> v;
int lyf[maxn*2];
signed main()
{
n=read(),m=read(),k=read();
ll l = -1e10,r=1e10;
int ymh=0;
for (int i=1;i<=m;i++)
{
e[i].u=read(),e[i].v=read(),e[i].w=read(),e[i].num=i;
if (e[i].u==1 || e[i].v==1) e[i].tag=1;
if (e[i].tag==1) ymh++;
}
ll ans=0;
//cout<<ymh<<endl;
while(r>=l)
{
ll mid = (l+r)/2;
for (int i=1;i<=m;i++) if(e[i].tag) e[i].w+=mid;
int tmp = solve();
//cerr<<"*"<<mid<<" "<<tmp<<endl;
if (tmp<=k) r=mid-1,ans=mid;
else l=mid+1;
for (int i=1;i<=m;i++) if (e[i].tag) e[i].w-=mid;
}
//cerr<<ans<<endl;
int ptx=0;
for (int i=1;i<=m;i++) if (e[i].tag) e[i].w+=ans;
for (int i=1;i<=n;i++) fa[i]=i;
sort(e+1,e+1+m,cmp1);
for (int i=1;i<=m;i++)
{
int f1 = find(e[i].u);
int f2 = find(e[i].v);
if (f1==f2) continue;
fa[f1]=fa[f2];
if (e[i].tag==1) lyf[e[i].num]=1;
}
for (int i=1;i<=n;i++) fa[i]=i;
for (int i=1;i<=m;i++)
{
if (lyf[e[i].num])
{
int f1 = find(e[i].u);
int f2 = find(e[i].v);
if (f1==f2) continue;
fa[f1]=fa[f2];
ptx+=e[i].tag;
v.pb(e[i].num);
}
}
//cout<<ptx<<endl;
if (ptx>k)
{
cout<<-1;
return 0;
}
//for (int i=1;i<=n;i++) fa[i]=i;
//cerr<<ptx<<endl;
sort(e+1,e+1+m,cmp);
for (int i=1;i<=m;i++)
{
int f1 = find(e[i].u);
int f2 = find(e[i].v);
if (f1==f2) continue;
if (ptx==k && e[i].tag==1) continue;
fa[f1]=fa[f2];
v.pb(e[i].num);
if (e[i].tag==1) ptx++;
}
//cerr<<ptx<<endl;
if(ptx!=k || v.size()!=n-1)
{
cout<<-1;
return 0;
}
cout<<n-1<<endl;
for (int i=0;i<v.size();i++) cout<<v[i]<<" ";
return 0;
}
//final
CF125E MST company (凸优化+MST)的更多相关文章
- 洛谷2619/bzoj2654 Tree(凸优化+MST)
bzoj的数据是真的水.. qwq 由于本人还有很多东西不是很理解 qwq 所以这里只写一个正确的做法. 首先,我们会发现,对于你选择白色边的数目,随着数目的上涨,斜率是单调升高的. 那么这时候我们就 ...
- 【CF125E】MST Company(凸优化,最小生成树)
[CF125E]MST Company(凸优化,最小生成树) 题面 洛谷 CF 题解 第一眼看见就给人丽洁姐那道\(tree\)一样的感觉. 那么二分一个权值,加给所有有一个端点是\(1\)的边, 然 ...
- luogu CF125E MST Company wqs二分 构造
LINK:CF125E MST Company 难点在于构造 前面说到了求最小值 可以二分出斜率k然后进行\(Kruskal\) 然后可以得到最小值.\(mx\)为值域. 得到最小值之后还有一个构造问 ...
- CodeForces 125E MST Company
E. MST Company time limit per test 8 seconds memory limit per test 256 megabytes input standard inpu ...
- 机器学习&数据挖掘笔记_15(关于凸优化的一些简单概念)
没有系统学过数学优化,但是机器学习中又常用到这些工具和技巧,机器学习中最常见的优化当属凸优化了,这些可以参考Ng的教学资料:http://cs229.stanford.edu/section/cs22 ...
- paper 110:凸优化和非凸优化
数学中最优化问题的一般表述是求取,使,其中是n维向量,是的可行域,是上的实值函数.凸优化问题是指是闭合的凸集且是上的凸函数的最优化问题,这两个条件任一不满足则该问题即为非凸的最优化问题. 其中,是 凸 ...
- 凸优化简介 Convex Optimization Overview
最近的看的一些内容好多涉及到凸优化,没时间系统看了,简单的了解一下,凸优化的两个基本元素分别是凸函数与凸包 凸集 凸集定义如下: 也就是说在凸集内任取两点,其连线上的所有点仍在凸集之内. 凸函数 凸函 ...
- 【Codeforces 321E / BZOJ 5311】【DP凸优化】【单调队列】贞鱼
目录 题意: 输入格式 输出格式 思路: DP凸优化的部分 单调队列转移的部分 坑点 代码 题意: 有n条超级大佬贞鱼站成一行,现在你需要使用恰好k辆车把它们全都运走.要求每辆车上的贞鱼在序列中都是连 ...
- 2019.03.12 codeforces739E. Gosha is hunting(dp凸优化)
传送门 题意:nnn个物品,有aaa个XXX道具和bbb个YYY道具,XXX道具移走第iii个物品概率为pip_ipi,YYY道具移走第iii个道具概率为uiu_iui. 对于每个物品每种道具最多 ...
随机推荐
- Dubbo | Dubbo快速上手笔记 - 环境与配置
目录 前言 1. Dubbo相关概念 1.1 自动服务发现工作原理 2. 启动文件 2.1 zookeeper-3.4.11\bin\zkServer.cmd 2.2 zookeeper-3.4.11 ...
- JS 根据文件路径获取名字和后缀名
var fileName = this.from.doc.substring(this.from.doc.lastIndexOf('/')+1); //文件名 var extNam ...
- netty系列之:搭建HTTP上传文件服务器
目录 简介 GET方法上传数据 POST方法上传数据 POST方法上传文件 总结 简介 上一篇的文章中,我们讲到了如何从HTTP服务器中下载文件,和搭建下载文件服务器应该注意的问题,使用的GET方法. ...
- Spring Cloud Apollo 实践
接上一篇Windows下安装Apollo的常见问题,安装完毕后试着看怎么来使用一下. 首先到管理页面创建一个新的应用: 创建成功后会自动跳转到应用的维护界面,如下图所示: 新增一个配置信息来进行后续的 ...
- Qt 6.0精简WebEngine SerialPort Multimedia等成为半残GUI框架一览
由于 Qt 集成了大量成熟模块,使之成为 C++ 领域中最好用的开源技术跨平台 GUI 开发框架.基于 Qt 能开发 Windows MacOS 传统桌面或无 GUI 应用程序.Unix/Linux ...
- uboot命令简介
uboot下的命令行 1.典型嵌入式linux系统启动过程: 嵌入式系统上电后先执行uboot.然后uboot负责初始化DDR,初始化Flash,然后将OS从Flash中读取到DDR中,然后启动OS( ...
- VUE002. 动态使用webpack打包处理后的静态图片路径({ img: require('xxx.png') })
案例摘要 需求是通过v-for循环渲染数组中数据,其中包括本地包的图片文件.话不多说直接上代码: <a-radio-group class="template-radio"& ...
- 枚举类enum
一.枚举类 package com.xxx.xf.common.enums; import com.xxx.xf.workday.contant.HolidayContant; /** * @Auth ...
- 详解C3P0(数据库连接池)
详解C3P0(数据库连接池) 快速索引 一.基本定义 二.使用C3P0(数据库连接池)的必要性 1.JDBC传统模式开发存在的主要问题 三.数据库连接池的详细说明 四.使用连接池的明显优势 1.资源的 ...
- HCNP Routing&Switching之IS-IS路由聚合和认证
前文我们了解了IS-IS路由渗透和开销相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15302382.html:今天我们来聊一聊IS-IS路由聚合和认 ...