bzoj的数据是真的水。。

qwq

由于本人还有很多东西不是很理解

qwq

所以这里只写一个正确的做法。

首先,我们会发现,对于你选择白色边的数目,随着数目的上涨,斜率是单调升高的。

那么这时候我们就可以考虑凸优化,也就是\(wqs\)二分来满足题目中所述的正好\(k\)条边的限制。

我们\(erf\)一个\(mid\),然后让每一个白边的权值都加上\(mid\),然后跑\(MST\),看最后的选的白色边数,是否是大于等于\(k\)的,如果是,就调大\(l\),否则调小\(r\)。

由于最小生成树选择边的时候可能有一些玄学的错误,所以我们在\(sort\)的时候,对于权值相等的边,我们优先选择白边。

那么通过\(erf\),之后,我们就能得到一个上界,也就是在当前的偏移量下,我们最多的选和1相连的边的个数。

根据\(clj\)的官方题解,这里有两个引理

对于一个图,如果存在一个最小生成树,它的白边的数量是\(x\),那么就称\(x\)是最小合法白边数。所有的最小合法白边数形成一个区间\([l,r]\)

(因为题目保证有解,所以我们只需要找到最小的\(r\)即可)

那么经过这个\(erf\),我们就能得到一个最小的\(r\)

那么我们应该怎么求整个\(MST\)的权值呢,我们会发现,对于权值相等的白边和黑边,由于题目保证有解,所以一定是会存在相互替代的关系的。

那我们可以按照之前的最小生成树的策略选白边,将其记为\(val\),最后输出\(val-k*ans\),\(ans\)表示最后的\(mid\)。

为什么是\(k\)而不是具体的选的边的数目呢?

因为题目要求正好选择\(k\)条,而我们这里实际上是把多余的白边都直接视为黑边来做了

qwqwq

那么这个题就能解决了

qwqwqwqwq

但是我根据CF125E那个题,有一个比较特殊的做法,但是套到这个这个题,我并不是很理解。qwq

这个坑还是之后再填吧

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<vector>
#define mk make_pair
#define pb push_back
#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 = 4e5+1e2;
struct Edge{
int u,v,w;
int col;
};
Edge e[maxn];
int n,m;
int ans;
int l=-200,r=200;
int fa[maxn];
int find(int x)
{
if (fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
int k;
bool cmp(Edge a,Edge b)
{
if (a.w==b.w) return a.col<b.col;
return a.w<b.w;
}
int solve()
{
sort(e+1,e+1+m,cmp);
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;
//if(tot==k && e[i].col==0) continue;
if (e[i].col==0) ++tot;
fa[f1]=fa[f2];
}
return tot;
}
signed main()
{
n=read(),m=read();k=read();
for (int i=1;i<=m;i++)
{
e[i].u=read()+1;
e[i].v=read()+1;
e[i].w=read();
e[i].col=read();
}
while(l<=r)
{
int mid = (l+r) >> 1;
for (int i=1;i<=n;i++) fa[i]=i;
for (int i=1;i<=m;i++)
{
if (e[i].col==0) e[i].w+=mid;
}
int tmp = solve();
if (tmp<k)
{
r=mid-1;
}
else l=mid+1,ans=mid;
for (int i=1;i<=m;i++)
{
if (e[i].col==0) e[i].w-=mid;
}
}
for (int i=1;i<=n;i++) fa[i]=i;
for (int i=1;i<=m;i++)
if (e[i].col==0) e[i].w+=ans;
sort(e+1,e+1+m,cmp);
int tot=0,val=0;
for (int i=1;i<=m;i++)
{
int f1 = find(e[i].u);
int f2 = find(e[i].v);
if (f1==f2) continue;
if (e[i].col==0) ++tot;
fa[f1]=fa[f2];
val+=e[i].w;
}
cout<<val-k*ans;
return 0;
}

洛谷2619/bzoj2654 Tree(凸优化+MST)的更多相关文章

  1. BZOJ2654 & 洛谷2619:tree——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2654 https://www.luogu.org/problemnew/show/P2619 给你 ...

  2. 洛谷 P4072 [SDOI2016]征途 斜率优化DP

    洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...

  3. CF125E MST company (凸优化+MST)

    qwq自闭的一个题 我来修锅辣!!!!!! 这篇题解!可以\(hack\)全网大部分的做法!!! 首先,我们可以把原图中的边,分成两类,一类是与\(1\)相连,另一类是不与\(1\)相连. 原题就转化 ...

  4. 洛谷 P5853 - [USACO19DEC]Tree Depth P(生成函数+背包)

    洛谷题面传送门 神仙题. 首先考虑一个点的深度是什么,注意到对于笛卡尔树而言直接从序列的角度计算一个点的深度是不容易的,因为这样会牵扯到序列中多个元素,需要 fixed 的东西太多,计算起来太复杂了. ...

  5. 洛谷.2619.[国家集训队2]Tree I(带权二分 Kruskal)

    题目链接 \(Description\) 给定一个无向带权连通图,每条边是黑色或白色.求一棵最小权的恰好有K条白边的生成树. \(Solution\) Kruskal是选取最小的n-1条边.而白边数有 ...

  6. [BZOJ2654]tree(二分+MST)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2654 分析:此题很奇葩,我们可以给所有白边加上一个权值mid,那么在求得的MST中白边 ...

  7. [bzoj4443] [loj#2006] [洛谷P4251] [Scoi2015]小凸玩矩阵

    Description 小凸和小方是好朋友,小方给小凸一个 \(N \times M\)( \(N \leq M\) )的矩阵 \(A\) ,要求小秃从其中选出 \(N\) 个数,其中任意两个数字不能 ...

  8. 洛谷 P3994 高速公路(斜率优化)

    题目链接 题意:给出一棵树,\(1\) 号点为根,边上有边权. 每个点有两个参数 \(p_i,q_i\) 如果你想从 \(i\) 号点到与其距离为 \(d\) 的 \(j\) 号点,那么你需花费 \( ...

  9. 洛谷P4250 [SCOI2015]小凸想跑步(半平面交)

    题面 传送门 题解 设\(p\)点坐标为\(x_p,y_p\),那么根据叉积可以算出它与\((i,i+1)\)构成的三角形的面积 为了保证\(p\)与\((0,1)\)构成的面积最小,就相当于它比其它 ...

随机推荐

  1. mycat<三>

    server.xml文件 <?xml version="1.0" encoding="UTF-8"?> <!-- - - Licensed u ...

  2. ASP截取字符 截取字符之间的字符

    ASP截取字符:MID函数Mid(变量或字串符,开始字节, 结尾字节(可不填)) InStrRev(变量, "字串符")  最后出现位置InStr(变量, "字串符&qu ...

  3. 前端性能优化(四)——网页加载更快的N种方式

    网站前端的用户体验,决定了用户是否想要继续使用网站以及网站的其他功能,网站的用户体验佳,可留住更多的用户.除此之外,前端优化得好,还可以为企业节约成本.那么我们应该如何对我们前端的页面进行性能优化呢? ...

  4. 剑指 Offer 36. 二叉搜索树与双向链表

    剑指 Offer 36. 二叉搜索树与双向链表 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表.要求不能创建任何新的节点,只能调整树中节点指针的指向. 为了让您更好地理解问题,以下面的 ...

  5. 我的第一个npm包:wechat-menu-editor 基于Vue的微信自定义菜单编辑器

    wechat-menu-editor 微信自定义菜单编辑器 前言 在做微信公众号相关开发时,基本上会去开发的功能就是微信自定义菜单设置的功能,本着不重复造轮子的原则,于是基于Vue封装的一个微信自定义 ...

  6. 硕盟type-c转接头|四合一多功能扩展坞

    硕盟SM-T54是一款 TYPE C转HDMI+VGA+USB3.0+PD3.0四合一多功能扩展坞,支持四口同时使用,您可以将含有USB 3.1协议的电脑主机,通过此产品连接到具有HDMI或VGA的显 ...

  7. K8s工作流程详解

    在学习k8s工作流程之前,我们得再次认识一下上篇k8s架构与组件详解中提到的kube-controller-manager一个k8s中许多控制器的进程的集合. 比如Deployment 控制器(Dep ...

  8. 【Sass/SCSS 完整自学中文版教程01】SCSS 官方英文文档翻译整理

    Sass 基本介绍 目录 Sass 基本介绍 注释(Comments) 单行注释(Single-line comments) 多行注释(Multi-line comments) SassDoc 特殊的 ...

  9. 记录一次C语言中free(p)失败

    首先介绍一下自己的程序出错的原因,然后总结一下什么时候free会失败. 1.程序伪代码 // 已知payload已经指向一部分内存数据 char * payload; int payload_len; ...

  10. selenium用css、xpath表达式进行元素定位

    绝对路径选择 从根节点开始的,到某个节点,每层都依次写下来,每层之间用 / 分隔的表达式,就是某元素的 绝对路径 Xpath : /html/body/div CSS : html>body&g ...