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. 手动设置IDEA失效的配置文件

  2. 接口自动化-python+requests+pytest+csv+yaml

    本套代码和逻辑 是本人的劳动成果,如果有转载需要标注, 非常适合公司做项目的同学!!!小白也可以学哦! 1.项目目录  2.公共方法的封装 2.1如果不用配置文件 可以使用这个方法进行封装--但是有一 ...

  3. JavaScript高级程序设计学习笔记之事件

    1.事件流 事件流描述的是从页面中接收事件的顺序. 事件冒泡 IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播 ...

  4. golang redis

    安装 下载第三方包: go get -u github.com/go-redis/redis/v9 连接 // 定义一个rdis客户端 var redisdb *redis.Client // 初始化 ...

  5. vue3 项目 用 vue-video-player 做直播 ( 亲测可用 )

    npm 安装 npm install --save vue-video-player npm install --save videojs-flash 1 <template> 2 < ...

  6. Nginx:无处不在的Nginx的八个应用场景与配置

    --- 阅读时间约 15 分钟 --- Nginx概述 众所周知,互联网已经离不开  WEB服务器  ,技术领域中  WEB服务器  不止  Nginx  一个,其他还有很多如  Apache  . ...

  7. 如何解决浮动元素高度塌陷---CSS

    解决高度塌陷问题的方法: 方法一. //给父元素添加声明 overflow:hidden; 缺点:回隐藏溢出的元素: 方法二. 在浮动的元素下添加空div标签,并给该元素添加声明: clear:bot ...

  8. 学习Tomcat(二)之容器概览

    Tomcat容器的Server模块有管理容器的启动和关闭.管理了容器内的服务组件Service.管理了全局JNDI资源的功能,对Tomcat容器的生命周期管理有重要意义.Tomcat的服务组件则是To ...

  9. Docker安装GitLab与Runner(网关),常规设置,自动化用到k8s+token

    [转]图文详解k8s自动化持续集成之GitLab CI/CD Windows里面使用Debian命令行工具完成 和Docker网络相关的命令 查看某一个容器的网络 docker inspect 容器I ...

  10. linux7可以通过远程和localhost访问mysql,但是127.0.0.1不能访问

    网上搜索的其他方法都试过,不行 比如设置权限,开放端口,配置数据库... 最好偶然一个搜索查看可能原因是防火墙端口问题: vim /etc/sysconfig/iptables 在文件中添加下面语句 ...