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. 对于每个物品每种道具最多 ...
随机推荐
- springcloud<zuul过滤器简单配置与跨域设置>
package com.wangbiao.config; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.Req ...
- 前端调用后台接口下载word文档的两种方法
1传统的ajax虽然能提交到后台,但是返回的数据被解析成json,html,text等字符串,无法响应浏览器下载.就算使用bob模拟下载,数据量大时也不方便 废话不多说:上代码(此处是Layui监听提 ...
- Learning ROS: Using a C++ class in Python
http://wiki.ros.org/ROS/Tutorials/Using%20a%20C%2B%2B%20class%20in%20Python This tutorial illustrate ...
- Learning ROS: Managing System dependencies
Download and install the system dependencies for turtlesim: roscd turtlesim cat package.xml rosdep i ...
- Nginx从安装到虚拟主机、https加密、重定向的设置
编译前的设置: 在源代码文件中把版本号注释掉,这是为了防止针对特定版本的恶意攻击 关闭编译时的调试模式 解决编译前的依赖性 进行配置参数: 对参数进行解读: 编译和安装: 做软链接方便调用: 创建ng ...
- Linux常用命令 - less命令详解
21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 查看文 ...
- Linux 配置Maven(避免踩坑篇)
前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 一.访问Maven官网下载压缩文件. 二.下载好的maven安装包放在磁盘的 /usr/local/ 目录下,如下图: 三.解压该压缩文 ...
- 编写一个应用程序,利用数组或者集合, 求出"HELLO",“JAVA”,“PROGRAM”,“EXCEPTION”四个字符串的平均长度以及字符出现重复次数最多的字符串。
public class Number { public static void main(String[] args) { String[] arr = { "HELLO", & ...
- Php实现简易购物商城系统
实现功能: 1.系统功能模块包括: 1)登陆注册模块 包括验证码.找回密码.注册模块中要使用Ajax判断用户名是否已经存在,使用正则表达式判断电子邮件.手机号和用户密码的格式是否合法. 2)用户管理模 ...
- 2. Go并发编程--GMP调度
目录 1. 前言 1.1 Goroutine 调度器的 GMP 模型的设计思想 1.2 GMP 模型 1.3. 有关M和P的个数问题 1.4 P 和 M 何时会被创建 2. 调度器的设计策略 3. g ...