luogu P5633 最小度限制生成树 wqs二分
LINK:最小度限制生成树
还是WQS二分的模板题 不过相当于我WQS二分的复习题.
对于求出强制k个的答案 dp能做不过复杂度太高了。
世界上定义F(x)表示选出x个的答案 画成图像 其实形成了一个凸包。
利用斜率就可以去切这个凸包了。
二分这个斜率 不断的在凸包上切 知道值刚好等于题目中要求的k 有的时候可能会出现mid时为k-1 mid+1时是k的情况 此时可以优先白边选使得在mid时满足要求。
可能此时x>k的 不过可以证明可以构造出来k条边的情况 然后减掉这k条边的权值即可。
卡了下常 跑的挺快的。
code
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 100000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-9
#define sq sqrt
#define mod 998244353
#define S second
#define F first
#define op(x) t[x].op
#define d(x) t[x].d
#define Set(a,v) memset(a,v,sizeof(a))
#define pf(x) ((x)*(x))
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=500010,maxn=50010;
int n,m,s,k,cnt1,cnt2,cnt,all,ans;ll res;
int f[maxn];
struct wy
{
int x,y,z;
inline bool friend operator <(wy a,wy b){return a.z<b.z;}
}t[MAXN],w[maxn],tmp[MAXN];
inline int getfather(int x){return x==f[x]?x:f[x]=getfather(f[x]);}
inline bool merge(int x,int y)
{
int xx=getfather(x);
int yy=getfather(y);
if(xx==yy)return 0;
f[xx]=yy;return 1;
}
inline bool check(int x)
{
int i=1,j=1;
cnt=0,all=0;res=0;
rep(1,n,i)f[i]=i;
rep(1,m,v)
{
if(i<=cnt1&&j<=cnt2)
{
if(t[i].z-x<=w[j].z)
{
if(merge(t[i].x,t[i].y))++cnt,res+=t[i].z-x,++all;
++i;
}
else
{
if(merge(w[j].x,w[j].y))res+=w[j].z,++all;
++j;
}
continue;
}
if(i<=cnt1){if(merge(t[i].x,t[i].y))++cnt,res+=t[i].z-x,++all;++i;}
if(j<=cnt2){if(merge(w[j].x,w[j].y))res+=w[j].z,++all;++j;}
if(all==n-1)break;
}
return cnt>=k;
}
signed main()
{
//freopen("1.in","r",stdin);
get(n);get(m);get(s);get(k);
rep(1,n,i)f[i]=i;
rep(1,m,i)
{
int get(x),get(y),get(z);
if(x==s||y==s)t[++cnt1]=(wy){x,y,z};
else tmp[++cnt2]=(wy){x,y,z};
ans+=merge(x,y);
}
if(cnt1<k){puts("Impossible");return 0;}
if(ans!=n-1){puts("Impossible");return 0;}
rep(1,n,i)f[i]=i;
sort(t+1,t+1+cnt1);
sort(tmp+1,tmp+1+cnt2);
int ww=0;
rep(1,cnt2,i)if(merge(tmp[i].x,tmp[i].y))w[++ww]=tmp[i];
cnt2=ww;
int l=-INF,r=INF;
if(!check(r)){puts("Impossible");return 0;}
if(check(l)&&cnt!=k){puts("Impossible");return 0;}
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid))r=mid;
else l=mid+1;
}
check(l);
putl(res+(ll)k*l);return 0;
}
luogu P5633 最小度限制生成树 wqs二分的更多相关文章
- 决策单调性&wqs二分
其实是一个还算 trivial 的知识点吧--早在 2019 年我就接触过了,然鹅当时由于没认真学并没有把自己学懂,故今复学之( 1. 决策单调性 引入:在求解 DP 问题的过程中我们常常遇到这样的问 ...
- Luogu P2619 [国家集训队2]Tree I(WQS二分+最小生成树)
P2619 [国家集训队2]Tree I 题意 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有\(need\)条白色边的生成树. 题目保证有解. 输入输出格式 输入格式 ...
- luogu CF125E MST Company wqs二分 构造
LINK:CF125E MST Company 难点在于构造 前面说到了求最小值 可以二分出斜率k然后进行\(Kruskal\) 然后可以得到最小值.\(mx\)为值域. 得到最小值之后还有一个构造问 ...
- 关于WQS二分算法以及其一个细节证明
应用分析 它的作用就是题目给了一个选物品的限制条件,要求刚好选$m$个,让你最大化(最小化)权值, 然后其特点就是当选的物品越多的时候权值越大(越小). 算法分析 我们先不考虑物品限制条件, 假定我们 ...
- [总结] wqs二分学习笔记
论文 提出问题 在某些题目中,强制规定只能选 \(k\) 个物品,选多少个和怎么选都会影响收益,问最优答案. 算法思想 对于上述描述的题目,大部分都可以通过枚举选择物品的个数做到 \(O(nk^2)\ ...
- [九省联考2018]林克卡特树(DP+wqs二分)
对于k=0和k=1的点,可以直接求树的直径. 然后对于60分,有一个重要的转化:就是求在树中找出k+1条点不相交的链后的最大连续边权和. 这个DP就好.$O(nk^2)$ 然后我们完全不可以想到,将b ...
- SCUT - 365 - 鹏哥的数字集合 - wqs二分 - 斜率优化dp
https://scut.online/p/365 https://www.luogu.org/problemnew/solution/P2365 写这篇的时候还不是很明白,看一下这个东西. http ...
- CF802O-April Fools‘ Problem(hard)【wqs二分,优先队列】
正题 题目链接:https://www.luogu.com.cn/problem/CF802O 题目大意 \(n\)天每条有\(a_i\)和\(b_i\). 每条可以花费\(a_i\)准备至多一道题, ...
- luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分)
luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分) Luogu 题解时间 $ k $ 条边权为 $ 0 $ 的边. 是的,边权为零. 转化成选正好 $ k+1 $ 条链. $ ...
随机推荐
- JS断点调试,必备的javaScript的debug调试技巧
1.断点调试是啥?难不难? 断点调试其实并不是多么复杂的一件事,简单的理解无外呼就是打开浏览器,打开sources找到js文件,在行号上点一下罢了.操作起来似乎很简单,其实很多人纠结的是,是在哪里打断 ...
- .Net Core微服务入门全纪录(八)——Docker Compose与容器网络
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 前言 上一篇[.Net Core微服务入门全纪录(七)--IdentityServer4-授权认证]中使用IdentityServer4 ...
- 2020年Java基础高频面试题汇总(1.4W字详细解析,你能遇到的都在这了)
1. Java语言有哪些特点 (1)简单易学.有丰富的类库 (2)面向对象(Java最重要的特性,让程序耦合度更低,内聚性更高) (3)与平台无关性(JVM是Java跨平台使用的根本) (4)可靠安全 ...
- Mysql基础(一):Mysql初识、基本指令、数据库密码相关、创建用户及授权
来源:https://www.cnblogs.com/liubing8/p/11432534.html 目录 数据库01 /Mysql初识.基本指令.数据库密码相关.创建用户及授权 1. 数据库概述 ...
- Mysql基础(九):MySQL 事务
一.含义事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行二.特点(ACID)A 原子性:一个事务是不可再分割的整体,要么都执行要么都不执行C 一致性:一个事务可以使数据 ...
- web 部署专题(八):Nginx 反向代理中cookie相关问题
问题3:认证问题 Domino服务器中,通过写了一些接口代码,提供RESTful的服务,来对手机端进行提供服务.但是由于原来的环境,没有SSO,而且不通过认证,没法访问到Domino里面的接口代码. ...
- Configurate vim tool
vim tool is a commom editor, for the sake of improving effeicient, it is necessary to configurate vi ...
- vue 仿掘金评论列表
先来个最终效果 代码: template代码: <template> <div class="main"> <div class="titl ...
- vscode安装rainbow-fart(彩虹屁)插件,程序员只能自我鼓励了!!!
2020-7-10更新 Rainbow Fart 插件现以发布到 VSCode 商店,安装过 VSIX 版本的用户请卸载之前的版本,从商店安装. 从 VSCode 扩展商店 下载并安装.(更新vsco ...
- Ubuntu虚拟机设置共享文件夹
Ubuntu虚拟机设置共享文件夹 注:个人笔记,小白笔记. 点击设置 进入到Ubuntu 中 cd /mnt/hgfs/ 后 我们会看到自己设置的共享文件夹.