首页 > 其他分享 >题解 [ARC165C] Social Distance on Graph

题解 [ARC165C] Social Distance on Graph

时间:2023-09-20 13:13:11浏览次数:41  
标签:二分 Distance return color 题解 LL mid 顶点 ARC165C

赛时:看不懂题,啊这!

赛后:就这?


题目描述

有一个简单相连的无向图,其顶点数为 \(n\),编号为 \(1\) 至 \(n\)。图中有 \(m\) 条加权边,第 \(i\) 条边连接顶点 \(a_i\) 和 \(b_i\),权重为 \(w_i\)。此外,连接两个顶点的简单路径的权重是简单路径中包含的边的权重之和。

我们给每个顶点涂上红色或蓝色。求满足以下条件的着色的整数 \(x\) 的最大值:对于连接涂有相同颜色的两个不同顶点的每一条简单路径,简单路径的权重至少为 \(x\)。

具体思路

显然二分查找最大的 \(x\),考虑 check 函数怎么打。

首先,对于权值大于 \(x\) 的边,对答案不会造成任何影响,因为几条比 \(x\) 大的边怎么加也不会比 \(x\) 小。

然后,考虑权值小于 \(x\) 的边,那么它连接的两个顶点一定不能染成一种颜色。于是我们给权值小于 \(x\) 的边连接的所有点跑一遍二分图染色,能染色说明当前的 \(x\) 可行,反之不行。

但是我们直接染色是不行的,因为我们还没考虑染色后,相同颜色的点之间的距离大于等于 \(x\)。

我们只需要考虑两条边即可,因为多条边也是一样的。我们可以预处理出每个点连着边的最小边权与次小边权的和,然后取一个最小值,这样选出来的最小值就是整个图里面任意两点距离的最小值。我们把这个东西设为二分的上界,就可以保证枚举的 \(x\) 小于等于任意两条边的和,即任意相同颜色的点距离大于等于 \(x\)。

要注意一点的是,二分的 \(l\) 和 \(r\) 极限情况下是会到 \(2e9\) 的,这个时候你 \(mid=(l+r)/2\) 一加,就会爆 int,所以记得要开 long long

设 \(w\) 为二分上界,时间复杂度:\(O(n \log w)\)。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N=2e5+5;
const LL inf=0x3f3f3f3f;
struct edge{LL x,y,c,pre;}a[2*N];LL last[N],alen;
void ins(LL x,LL y,LL c){
	a[++alen]=edge{x,y,c,last[x]};
	last[x]=alen;
}
LL n,m,color[N];
LL minn[N],next_minn[N];
void solve(LL x,LL c){
	if(c<minn[x]){
		next_minn[x]=minn[x];
		minn[x]=c;
	}
	else if(minn[x]<=c&&c<next_minn[x]){
		next_minn[x]=c;
	}
}
bool dfs(LL x,LL mid,LL c){
	color[x]=c;
	for(LL k=last[x];k;k=a[k].pre){
		if(a[k].c>=mid)continue;
		LL y=a[k].y;
		if(color[x]==color[y])
			return false;
		if(!color[y]&&!dfs(y,mid,3-c))
			return false;
	}
	return true;
}
bool check(LL mid){
	memset(color,0,sizeof(color));
	for(LL i=1;i<=n;i++)
		if(!color[i])
			if(!dfs(i,mid,1))
				return false;
	return true;
}
int main(){
	scanf("%lld%lld",&n,&m);
	alen=1;memset(last,0,sizeof(last));
	memset(minn,0x3f,sizeof(minn));
	memset(next_minn,0x3f,sizeof(next_minn));
	for(LL i=1;i<=m;i++){
		LL x,y,c;scanf("%lld%lld%lld",&x,&y,&c);
		ins(x,y,c),ins(y,x,c);
		solve(x,c),solve(y,c);
	}
	LL l=0,r=2e9,ans;
	for(LL i=1;i<=n;i++){
		r=min(r,minn[i]+next_minn[i]);
	}
	while(l<=r){
		LL mid=(l+r)>>1;
		if(check(mid)){
			l=mid+1;
			ans=mid;
		}
		else r=mid-1;
	}
	printf("%d",ans);
	return 0;
}

标签:二分,Distance,return,color,题解,LL,mid,顶点,ARC165C
From: https://www.cnblogs.com/reclusive2007/p/17717056.html

相关文章

  • QOJ61 Cut Cut Cut! 题解
    题面。题解假设\(1\)号点有\(d\)条出边,给\(d\)条出边赋\(d\)个独立的单位向量,接下来,每个出边记作入边的随机线性组合,那么对于第\(i\)个点,答案就是入边生成的线性空间的秩。正确性证明:对于每个点考虑,假设现在考虑\(i\)号点,将其入边集合记作\(E1_{i}\),出边集合记......
  • 9.20周三(动手动脑问题解决)
    无法编译原因:没有默认构造推出结论:当你给类提供了一个自定义的构造方法,导致系统不在提供默认构造方法了,需要自己提供初始化测试packageorg.example;publicclassInitializeBlockClass{publicintfield=100;{field=200;}publicInitiali......
  • Acwing393. 雇佣收银员 题解 差分约束
    题目链接:https://www.acwing.com/problem/content/description/395/解题思路:差分约束。为了方便起见,定义第\(i\)个时间段为\(i-1:00\)到\(i:00\)这个时间段。首先,为了方便开一个额外的点,令\(R_i\)对应为题目中的\(R(i+1)\),即\(R_i\)表示\(i-1:00\)到\(i:00\)这......
  • 微软自带拼音输入法不显示选字框的问题解决
    运行框、聊天框都不显示右击右下角的图标-设置-常规-兼容性拉到最下面有个“兼容性”,勾选即可现在OK了......
  • CF1767C Count Binary Strings 题解
    CF1767CCountBinaryStrings题解Foreword感谢@樱雪喵、@swiftc两位大佬的耐心指导。Links洛谷CodeforcesDescription有一个长度为\(n\)的01串\(s\)(下标从\(1\)开始)和一些限制\(a_{i,j}(1\lei\lej\len)\)。\(a_{i,j}\)的含义如下:\(a_{i,j}=\)含义......
  • 【POJ 3278】Catch That Cow 题解(深度优先搜索)
    农夫约翰已被告知一头逃亡奶牛的位置,并想立即抓住她。他从一条数字线上的N点(0≤N≤100000)开始,奶牛在同一条数字线上的K点(0≥K≤100000)。农夫约翰有两种交通方式:步行和坐车。*步行:FJ可以在一分钟内从任何点X移动到点X-1或X+1*坐车:FJ可以在一分钟内从任何X点移动到2×X点。如果奶......
  • 「2019 集训队互测 Day 3」操作序列计数 题解
    简化题意:对于每一个$L$,求出有多少个长度为$L+1$的非负整数序列$a$,满足$\sum_{i=0}^{L}a_ik^i\leqn$,并且$a_{L}>0$。我们注意题目要求的和是小于等于一个数,这不太方便。我们可以把它转化成和等于一个数的形式,其实就是和为$nk$的方案数,这就相当于在最后的和后面乘上一......
  • 【题解】CF1817 合集
    CF1817AAlmostIncreasingSubsequence考虑几乎上升的序列的长度,就是我们的区间长度减去\(a_{i-2}\geqa_{i-1}\geqa_i\)的对数,然后维护即可,当然个人感觉自己的代码有点长,可以考虑看洛谷题解代码code:#include<bits/stdc++.h>usingnamespacestd;constintNN=2e5+......
  • CF840C 题解
    一、题目描述:给你一个长度为$n$的序列$a_1\sima_n$,$0\lea_i\le1\times10^9$。求有多少种$1\simn$的全排列$b$,使得对于$i\in[2,n],a_{b_i}\timesa_{b_{i-1}}$不是完全平方数。本题中完全平方数的定义:若存在某个整数$k$,使得$k^2=x$,则$x$是一个......
  • 9.18CF1817题解
    9.18CF1817题解A.AlmostIncreasingSubsequence题意给定长度为\(n\)一个序列\(a\)以及\(q\)次询问,每次询问给出\(l\)和\(r\),找出序列\(a\)在\([l,r]\)内最长的几乎递增子序列。对于几乎递增的定义:如果一个序列中不存在连续的三个数\(x\),\(y\),\(z\),使得\(x\g......