202609 GESP 八级 T2 题解(假了)

场切好评。

upd on 9.14 思路是假的,但 CCF 数据水让我过了。

思路

本题中第 \(i\) 条地铁线的列车从 \(u_i\) 出发单向开往 \(v_i\)(注意:中间一站不停),运行时间为 \(t_i\)。
应该很容易发现地铁线路的数据与带权有向图是一样的,所以考虑建图。

我们又注意到 \(n\le 500\),于是考虑乱搞:对于每组询问暴力跑一遍 Dijkstra,然后看能否到达。

代码实现

Dijkstra 的实现需要注意一些点:

  1. 一开始把起始点放进堆的时候花费要设置为 \(s\),这个应该很容易发现。
  2. 在尝试松弛边时需要检查当前时间花费是否小于 \(l_i\)。

具体代码

#include <bits/stdc++.h>
using namespace std;
const int N=507;
const int M=1007;

int n,m,q;

int l[M];
struct Edge{
	int to,w,id;
};
vector<Edge> T[N];

struct Node{
	int to,w;
	bool operator <(const Node&ot)const{
		return w<ot.w;
	}
};
int vis[N];
int dij(int fr,int to,int s){
	//     from   to   start time
	memset(vis,0x3f,sizeof(vis));
	priority_queue<Node> q;
	q.push({fr,s});
	while(!q.empty()){
		Node now=q.top();
		q.pop();
		if(now.w>vis[now.to]){
			continue;//最优性剪枝
		}
		if(now.to==to){
			return now.w;
		}
		for(auto e:T[now.to]){
			if(e.w+now.w<vis[e.to]&&now.w<=l[e.id]){
				vis[e.to]=e.w+now.w;
				q.push({e.to,e.w+now.w});
			}
		}
	}
	return -1;
}
signed main(){
	cin.tie(0)->sync_with_stdio(0);
	cin>>n>>m>>q;
	for(int i=1,u,v,w;i<=m;i++){
		cin>>u>>v>>l[i]>>w;
		T[u].push_back({v,w,i});
	}
	while(q--){
		int x,y,s;
		cin>>x>>y>>s;
		cout<<(dij(x,y,s)==-1?"No":"Yes")<<'\n';
	}
	return 0;
}
posted @ 2026-09-12 17:03  IterateRabbitwky  阅读(106)  评论(0)    收藏  举报