[CF1483D]Useful Edges

Posted Tan_tan_tann

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1483D]Useful Edges相关的知识,希望对你有一定的参考价值。

Useful Edges

题解

首先我们考虑如何判断一条边合法,我们定义 u , v u,v u,v之间的最短路为 d i s u , v dis_{u,v} disu,v,询问三元组的长度为 a s k u , v ask_{u,v} asku,v,记边为 ( x , y ) (x,y) (x,y),询问为 ( u , v ) (u,v) (u,v)
那么对于边 i i i,条件是
∃ j , d i s u j , x i + p a i d x i , y i + d i s y i , v j ⩽ a s k u j , v j \\exists j,dis_{u_{j},x_{i}}+paid_{x_{i},y_{i}}+dis_{y_{i},v_{j}}\\leqslant ask_{u_{j},v_{j}} j,disuj,xi+paidxi,yi+disyi,vjaskuj,vj
考虑移项,可得
∃ j , d i s u j , x i + p a i d x i , y i ⩽ a s k u j , v j − d i s y i , v j \\exists j,dis_{u_{j},x_{i}}+paid_{x_{i},y_{i}}\\leqslant ask_{u_{j},v_{j}}-dis_{y_{i},v_{j}} j,disuj,xi+paidxi,yiaskuj,vjdisyi,vj
我们可以枚举 u u u y y y,这样前面半截就只与 x x x相关,后面半截就只与 v v v相关。
那么,对于每个 ( u , y ) (u,y) (u,y),由于是存在,我们可以找到最大的 a s k u , v − d i s y , v ask_{u,v}-dis_{y,v} asku,vdisy,v,此后再枚举 x x x,如果有 d i s u , x + p a i d x , y ⩽ ( a s k u , v − d i s y , v ) max ⁡ dis_{u,x}+paid_{x,y}\\leqslant (ask_{u,v}-dis_{y,v})_{\\max} disu,x+paidx,y(asku,vdisy,v)max,则该边 ( x , y ) (x,y) (x,y)就是合法的。
我们只需要枚举 ( u , y ) (u,y) (u,y),算出该数对使得那些 x x x合法,最后统计合法的边数即可。
至于 d i s dis dis数组,可以先通过Floyed求出来。

时间复杂度 O ( n 3 ) O\\left(n^3\\right) O(n3)

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 300005
#define lowbit(x) (x&-x)
#define reg register
#define mp make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x3f3f3f3f;
const LL mo=1e9+7;
const LL inv2=5e8+4;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int n,m,q,paid[605][605],dis[605][605],ask[605][605],ans;bool vis[605][605];
struct edge{int u,v;}e[MAXN];
signed main(){
	read(n);read(m);memset(paid,0x3f,sizeof(paid));
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=m;i++){
		int u,v,w;read(u);read(v);read(w);e[i]=(edge){u,v};
		dis[u][v]=dis[v][u]=paid[u][v]=paid[v][u]=w;
	}
	for(int i=1;i<=n;i++)paid[i][i]=dis[i][i]=0;
	for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
		if(i!=j&&i!=k&&j!=k)dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
	//for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)printf("dis%d %d:%d\\n",i,j,dis[i][j]);
	read(q);
	for(int i=1,u,v,w;i<=q;i++)read(u),read(v),read(w),ask[u][v]=ask[v][u]=w;
	for(int u=1;u<=n;u++)
		for(int y=1;y<=n;y++){
			int maxx=0;for(int v=1;v<=n;v++)maxx=max(maxx,ask[u][v]-dis[y][v]);
			for(int xCF981C Useful Decomposition 树 dfs 二十三 *

[TIA PORTAL][CONVERT] Convert Char Array to DInt...DInt to Char Array..Useful and easy function(代码片段

CF981C Useful Decomposition树/思维

CF G. Orientation of Edges BFS

CF576E Painting Edges

CF1383F. Special Edges