首页 > 其他分享 >CF2057E2 Another Exercise on Graphs (hard version) 题解

CF2057E2 Another Exercise on Graphs (hard version) 题解

时间:2025-01-07 22:55:51浏览次数:1  
标签:ch CF2057E2 题解 短路 hard 边权 Exercise

感觉和 [NOI2018] 归程 有点像(?

考虑对每个询问二分答案,设二分到的答案是 \(x\),要判断路径上的 \(k\) 大值是否能不大于 \(x\),只需先将价值不大于 \(x\) 的所有边的边权设为 \(0\),其他边设为 \(1\),跑一遍 \(a\) 到 \(b\) 的最短路,看最短路长度是否不大于 \(k\) 即可。因为 \(x\) 的排名只和价值比它大的边的数量有关系,比它小的边可以随便走。

现在我们只需预处理出任意时刻任意两点间的最短路即可。将所有边按边权从小到大加入,显然如果一条边连接的两点已经被边权为 \(0\) 的边联通了,这条边加入就没什么意义了。每加入一条边就用类似 Floyd 的方法松弛一遍。总时间复杂度 \(O(n^3 + q\log n)\)。


#include<bits/stdc++.h>
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
	int ch=getchar();
	T f=1;x=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x*=f;rd(args...);
}
const int N=3e5+5,D=405,INF=1e9+7;
int T,n,m,q;
int dis[D][D][D],cnt,w[D];
struct node{int x,y,z;}e[N];
inline void Solve(){
	rd(n,m,q);cnt=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)dis[0][i][j]=INF;
	for(int i=1;i<=n;i++)dis[0][i][i]=0;
	for(int i=1;i<=m;i++){
		rd(e[i].x,e[i].y,e[i].z);
		dis[0][e[i].x][e[i].y]=dis[0][e[i].y][e[i].x]=1;
	}
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				dis[0][i][j]=std::min(dis[0][i][k]+dis[0][k][j],dis[0][i][j]);
			}
		}
	}
	std::sort(e+1,e+m+1,[](node a,node b){return a.z<b.z;});
	for(int i=1;i<=m;i++){
		if(dis[cnt][e[i].x][e[i].y]==0)continue;
		++cnt;w[cnt]=e[i].z;
		for(int j=1;j<=n;j++)
			for(int k=1;k<=n;k++)dis[cnt][j][k]=dis[cnt-1][j][k];
		dis[cnt][e[i].x][e[i].y]=0;
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++){
				dis[cnt][j][k]=std::min(dis[cnt][j][k],dis[cnt][j][e[i].x]+dis[cnt][e[i].y][k]);
				dis[cnt][j][k]=std::min(dis[cnt][j][k],dis[cnt][j][e[i].y]+dis[cnt][e[i].x][k]);
			}
		}
	}
	while(q--){
		int a,b,k;rd(a,b,k);
		int L=1,R=cnt;
		while(L<=R){
			int mid=(L+R)>>1;
			if(dis[mid][a][b]<=k-1)R=mid-1;
			else L=mid+1;
		}
		printf("%d\n",w[L]);
	}
}
signed main(){
	rd(T);
	while(T--)Solve();
	return 0;
}

标签:ch,CF2057E2,题解,短路,hard,边权,Exercise
From: https://www.cnblogs.com/11-twentythree/p/18658600

相关文章

  • Luogu P3041 USACO12JAN Video Game G 题解 [ 紫 ] [ AC 自动机 ] [ 动态规划 ]
    VideoGamesG:弱智紫题,30min切了,dp思路非常板。多模式串一看肯定就是要建出AC自动机,然后在fail树里下传标记,预处理每个节点到达后的得分。然后设计\(dp_{i,j}\)表示第\(i\)个字符,AC自动机里匹配节点在\(j\)的最大答案,刷表法转移即可:\[dp_{i+1,ch_{j,c}}\gets\ma......
  • HDU7521 cats 的二分答案 题解
    思路首先,转换一下题意。只有在\(val=0\)时,才会向左缩小范围。然而只有越界访问才能达成\(val=0\),因此实际上我们最多只能向左缩小范围\(k\)次。对于当前的二分区间,\(mid\)本身可以作为一个答案,同时还要加上左右两边子区间的贡献。因此想到可以递归计算子区间的贡献。......
  • 题解- 恢复数组
    题目描述有一个数组a[1…n],但是这个数组的内容丢失了,你要尝试恢复它。已知以下的三个事实:1、对于1<=i<=n,都有a[i]>0,且所有的a[i]互不相同。即a数组保存的全部都是正整数,且互不相同。2、x和y一定是属于数组a,且x<y。3、a数组是递增的数组,且相邻两项的差是相等的。即数组a......
  • 海贼OJ #251. 士兵 题解 排序+中位数(数学思维题)
    题目链接:https://oj.haizeix.com/problem/251解题思路:最短总距离是所有点到中位数的距离之和。对\(y\):排序求中位数。对\(x\):对\(x\)排序,然后对排序后的\(x_i-i\)排序,然后求最短距离。对\(x_i-i\)进行处理,能保证最终的\(x_i\)各不一样且相邻。示例程序:#inclu......
  • 题解:P1541 [NOIP2010 提高组] 乌龟棋
    基础动态规划。这道题的题目条件显然满足阶段性和无后效性,那么有一个直观的思路就是把当前所处格子和四种卡片的使用次数作为状态。但是如果按照上面的想法,数组空间是无法开下的,所以我们稍微变一下思路,把四种卡片的使用数量作为状态,对于当前所处格子的话可以直接计算出来,这样数......
  • P8037 [COCI2015-2016#7] Prokletnik 题解
    题意定义一个区间$l,r$为好的当且仅当最小值为$a_l$且最大值为$a_r$或最大值为$a_l$且最小值为$a_r$。我们先考虑最小值为$a_l$且最大值为$a_r$的,另一个我们翻转过来在搞一遍就好了。先考虑将询问离线按$r$排序,容易发现,对于每个右端点$r$对应的合法左端点是......
  • E. Beautiful Array(题解)
    原题链接:https://codeforces.com/problemset/problem/1986/E思路:排序,取模,思维关于操作:ai=ai+k;若要使a1+m1*k==a2+m2*k;则当a1,a2满足a1%k==a2%k,a1,a2可以满足a1+m1*k==a2+m2*k;并在需要(|a1-a2|)/k次操作。将a数组取模后,用vector分别储存,a1和a2相差越小,需要的次数越......
  • 题解:CF2043C Sums on Segments
    题意给你一个长度为\(n\)的数组\(a\),满足\(a\)中有且仅有一个不为\(1\)也不为\(-1\)的数(以下简称特殊的值),剩余的数都是\(1\)或\(-1\)。求所有可能的子区间的和的值(下文简称答案)。从小到大一次输出每一个值,每个值只输出一遍。题解首先,我们发现,如果把那个特殊的值考......
  • 题解:CF2057B Gorilla and the Exam
    CF2057BGorillaandtheExam思路不难发现其实每次操作就是把数组\(a\)内所有值为\(y\)的数都删除掉(\(y\)为数组\(a\)中的莫一个值)。所以我们需要把尽可能多的数都变成原来数组里出现次数最多的数(从出现数量最少的开始,这样能使得消失的数值种类最大化)。首先想到使用数组......
  • 题解:P11507 [ROIR 2017 Day 1] 计算器
    P11507[ROIR2017Day1]计算器思路简单的动态规划。\(dp_{i,j,k}\)表示使用了\(i\)次按钮A,\(j\)次按钮B和\(k\)次按钮C。转移式:\[\begin{cases}dp_{i+1,j,k}=\min(dp_{i+1,j,k},\lfloordp_{i,j,k}\div2\rfloor);\\dp_{i,j+1,k}=\min(dp_{i,j+1,k},\lfloo......