[usOJ5528]小奇的旅行计划

题目

传送门

题目描述
小奇所在的国家一共由 n n n个城市和 m m m条连接这些城市的双向道路组成。

小奇非常喜欢骑自行车,它常常骑着自行车从一个城市,沿着某些双向道路到达另一个城市。

现在,这个国家要关闭其所有的道路以便翻修,但为了保证必要的交通运输,第 i i i条道路会在第 i i i天暂时开放。

小奇为了了解本次翻修对它旅行的影响,因此想知道,如果它第 L \mathcal{L} L天在一个城市 s s s,在第 R \mathcal{R} R天或之前是否能到达城市 t t t。当然,小奇不需要第 L \mathcal{L} L天就立即离开 ,也不需要恰好在第 R \mathcal{R} R天到达城市 。

为了更全面地评估这个影响,小奇会有许多的询问,但它一下子算不过来,就只好找你帮忙了。

输入格式
第一行三个正整数 n , m , q n,m,q n,m,q,分别表示城市数、道路数、询问数。

接下来有 m m m行,其中第 i + 1 i+1 i+1行有两个正整数 u i , v i ( u i ≠ v i ) u_i,v_i(u_i\ne v_i) ui,vi(ui=vi),表示有一条连接 u i , v i u_i,v_i ui,vi两座城市的双向道路,并且这条道路在第 i i i天暂时开放。

接下来 q q q行,每行四个正整数 l i , r i , s i , t i l_i,r_i,s_i,t_i li,ri,si,ti,表示一个询问。

输出格式
q q q行,第 i i i行表示第 i i i个询问的答案,可行输出 Yes \text{Yes} Yes,不可行输出 No \text{No} No

数据范围与约定
对于 30 % 30\% 30%的数据, m , q ≤ 2000 m,q\le 2000 m,q2000

对于所有数据均有: 2 ≤ n ≤ 1000 , 1 ≤ m , q ≤ 200000 , 1 ≤ l i ≤ r i ≤ m , 1 ≤ s i , t i ≤ n , s i ≠ t i 2\le n\le 1000,1\le m,q\le 200000,1\le l_i\le r_i\le m,1\le s_i,t_i\le n,s_i\ne t_i 2n1000,1m,q200000,1lirim,1si,tin,si=ti

不保证整张图连通,不保证有且仅有一条道路连接两座城市。

思路

直接大力 D P \Bbb{DP} DP

f i ( x , y ) f_i(x,y) fi(x,y)表示第 i i i天在 x x x,最早什么时候到 y y y。对第 i i i天的行为进行决策,直接可以写出转移方程:(用 ( u , v ) (u,v) (u,v)表示边权)

f i ( x , y ) = min ⁡ [ f i + 1 ( x , y ) , min ⁡ ( x , z ) = i f i + 1 ( z , y ) ] f_{i}(x,y)=\min[f_{i+1}(x,y),\min_{(x,z)=i}f_{i+1}(z,y)] fi(x,y)=min[fi+1(x,y),(x,z)=iminfi+1(z,y)]

好像有 n 2 m n^2m n2m个状态?太多了吧!

仔细想想, f i + 1 ( ? , ? ) f_{i+1}(?,?) fi+1(?,?) f i ( ? , ? ) f_{i}(?,?) fi(?,?)的区别在哪里?只在于第 i i i条边的端点!只有第 i i i条边的端点不是从 f i + 1 ( ? , ? ) f_{i+1}(?,?) fi+1(?,?)直接拷贝过来的。

有点像长链剖分那种优化,使用 滚动数组。只需要从大到小枚举每一条边,进行状态转移即可。

等等!似乎会导致同层转移。也就是说, f i ( x , y ) f_i(x,y) fi(x,y)会从 f i ( z , y ) f_i(z,y) fi(z,y)转移过来。

但是没关系!因为上面这种转移也是对的(你走过去再走回来没人拦着你)。

代码

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
inline int readint(){
	int a = 0, f = 1; char c = getchar();
	for(; c<'0' or c>'9'; c=getchar())
		if(c == '-') f = -1;
	for(; '0'<=c and c<='9'; c=getchar())
		a = (a<<3)+(a<<1)+(c^48);
	return a*f;
}

const int MaxN = 1000;
int n, m, q;
struct Query{
	int L, R, S, T, id;
	void input(){
		L = readint(), R = readint();
		S = readint(), T = readint();
	}
	bool operator<(const Query &that)const{
		return L < that.L;
	}
}query[200001];
struct Edge{
	int one, two;
	void input(){
		one = readint(), two = readint();
	}
};
Edge ppl[200001];

void init(){
	n = readint(), m = readint(), q = readint();
	for(int i=1; i<=m; ++i)
		ppl[i].input();
	for(int i=1; i<=q; ++i){
		query[i].input();
		query[i].id = i;
	}
	sort(query+1,query+q+1);
}

int dp[MaxN+1][MaxN+1];
bool answers[200001];
void solve(){
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=n; ++j)
			dp[i][j] = (1<<20);
	int nowq = q;
	for(int i=m,x,y; i; --i){
		x = ppl[i].one, y = ppl[i].two;

		dp[x][y] = min(dp[x][y],i);
		dp[y][x] = min(dp[y][x],i);
		for(int j=1; j<=n; ++j){
			if(j != x) dp[y][j] = min(dp[y][j],dp[x][j]);
			if(j != y) dp[x][j] = min(dp[x][j],dp[y][j]);
		}
		while(nowq and query[nowq].L == i){
			answers[query[nowq].id] = (dp[query[nowq].S][query[nowq].T] <= query[nowq].R);
			-- nowq;
		}
	}
	for(int i=1; i<=q; ++i){
		if(answers[i]){
			putchar('Y');
			putchar('e');
			putchar('s');
		}
		else{
			putchar('N');
			putchar('o');
		}
		putchar('\n');
	}
}

int main(){
	// freopen("travel.in","r",stdin);
	// freopen("travel.out","w",stdout);
	init();
	solve();
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值