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)的更多相关文章

  1. 洛谷2619/bzoj2654 Tree(凸优化+MST)

    bzoj的数据是真的水.. qwq 由于本人还有很多东西不是很理解 qwq 所以这里只写一个正确的做法. 首先,我们会发现,对于你选择白色边的数目,随着数目的上涨,斜率是单调升高的. 那么这时候我们就 ...

  2. 【CF125E】MST Company(凸优化,最小生成树)

    [CF125E]MST Company(凸优化,最小生成树) 题面 洛谷 CF 题解 第一眼看见就给人丽洁姐那道\(tree\)一样的感觉. 那么二分一个权值,加给所有有一个端点是\(1\)的边, 然 ...

  3. luogu CF125E MST Company wqs二分 构造

    LINK:CF125E MST Company 难点在于构造 前面说到了求最小值 可以二分出斜率k然后进行\(Kruskal\) 然后可以得到最小值.\(mx\)为值域. 得到最小值之后还有一个构造问 ...

  4. CodeForces 125E MST Company

    E. MST Company time limit per test 8 seconds memory limit per test 256 megabytes input standard inpu ...

  5. 机器学习&数据挖掘笔记_15(关于凸优化的一些简单概念)

    没有系统学过数学优化,但是机器学习中又常用到这些工具和技巧,机器学习中最常见的优化当属凸优化了,这些可以参考Ng的教学资料:http://cs229.stanford.edu/section/cs22 ...

  6. paper 110:凸优化和非凸优化

    数学中最优化问题的一般表述是求取,使,其中是n维向量,是的可行域,是上的实值函数.凸优化问题是指是闭合的凸集且是上的凸函数的最优化问题,这两个条件任一不满足则该问题即为非凸的最优化问题. 其中,是 凸 ...

  7. 凸优化简介 Convex Optimization Overview

    最近的看的一些内容好多涉及到凸优化,没时间系统看了,简单的了解一下,凸优化的两个基本元素分别是凸函数与凸包 凸集 凸集定义如下: 也就是说在凸集内任取两点,其连线上的所有点仍在凸集之内. 凸函数 凸函 ...

  8. 【Codeforces 321E / BZOJ 5311】【DP凸优化】【单调队列】贞鱼

    目录 题意: 输入格式 输出格式 思路: DP凸优化的部分 单调队列转移的部分 坑点 代码 题意: 有n条超级大佬贞鱼站成一行,现在你需要使用恰好k辆车把它们全都运走.要求每辆车上的贞鱼在序列中都是连 ...

  9. 2019.03.12 codeforces739E. Gosha is hunting(dp凸优化)

    传送门 题意:nnn个物品,有aaa个XXX道具和bbb个YYY道具,XXX道具移走第iii个物品概率为pip_ipi​,YYY道具移走第iii个道具概率为uiu_iui​. 对于每个物品每种道具最多 ...

随机推荐

  1. ☕【Java技术指南】「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!

    前提介绍 本章主要介绍相关线程声明周期的转换机制以及声明周期的流转关系以及相关AQS的实现和相关的基本原理,配合这相关官方文档的中英文互译的介绍. 线程状态流转及生命周期 当线程被创建并启动以后,它既 ...

  2. 学习Tomcat(一)之容器概览

    Tomcat是Apache软件基金会的一个顶级项目,由Apache.Sun和其它一些公司及个人共同开发,是目前比较流行的Web服务器之一.Tomcat是一个开源的.小型的轻量级应用服务器,具有占用系统 ...

  3. VUE001. 拖动div盒子(自定义指令v-directives)

    拖动div是一个逻辑很简单的需求,监听容器的鼠标按下松开的事件,执行函数通过DOM改变标签的CSS偏移量. 在VUE构建的项目中,通过标签的 @mousedown 和 @mouseup 赋予行为事件, ...

  4. 原子操作cas

    一.概念, 基于处理器指令,把比较和交换合成一个指令完成,保证了原子性: 因为是针对一个内存地址值的,一个内存地址指向一个变量,所以只对一个共享变量能保证原子性: 二.原子操作类 锁只有synchro ...

  5. SpringBoot异步使用@Async原理及线程池配置

    前言 在实际项目开发中很多业务场景需要使用异步去完成,比如消息通知,日志记录,等非常常用的都可以通过异步去执行,提高效率,那么在Spring框架中应该如何去使用异步呢 使用步骤 完成异步操作一般有两种 ...

  6. 【AGC025B】RGB Color

    [AGC025B]RGB Color 题面描述 Link to Atcoder Link to Luogu Takahashi has a tower which is divided into \( ...

  7. 在Jupyter Notebook添加代码自动补全功能

    在使用Jupyter notebook时发现没有代码补全功能,于是在网上查找了一些资料,最后总结了以下内容. 1 安装显示目录功能: pip install jupyter_contrib_nbext ...

  8. Set代码

    现有一整数集(允许有重复元素),初始为空.我们定义如下操作:add x 把 x 加入集合del x 把集合中所有与 x 相等的元素删除ask x 对集合中元素x的情况询问 对每种操作,我们要求进行如下 ...

  9. Java多线程-1(3)

    本份随记主要为狂神老师的Java多线程教学的学习笔记,记载了视频中一些有关基础概念以及部分代码示例.随机分为1-3共三份,知识点记录的不是很深入,以后的学习过程中随时补充. 1 有关基础概念 1.1 ...

  10. ecshop商品自定义销量(虚拟销量)实现方法

    1.在sq执行语句   ALTER TABLE `ecs_goods` ADD `sales_volume_base` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0' ...