202609 GESP 八级 T2 题解(假了)
场切好评。
upd on 9.14 思路是假的,但 CCF 数据水让我过了。
思路
本题中第 \(i\) 条地铁线的列车从 \(u_i\) 出发单向开往 \(v_i\)(注意:中间一站不停),运行时间为 \(t_i\)。
应该很容易发现地铁线路的数据与带权有向图是一样的,所以考虑建图。
我们又注意到 \(n\le 500\),于是考虑乱搞:对于每组询问暴力跑一遍 Dijkstra,然后看能否到达。
代码实现
Dijkstra 的实现需要注意一些点:
- 一开始把起始点放进堆的时候花费要设置为 \(s\),这个应该很容易发现。
- 在尝试松弛边时需要检查当前时间花费是否小于 \(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;
}

浙公网安备 33010602011771号