洛谷P4880 抓住czx
思路还是不难的。
就是跑出来 \(lty\) 从起点到每个点的最短路,把 \(czx\) 到每个点的时间从小到大排序,然后把 \(lty\) 到每个点的时间与 \(czx\) 到下一个点的时间判断一下,如果 \(<\) 注意是小于,也就是说 \(lty\) 先到,直接输出较大的时间。
最后如果没有找到答案,直接输出 \(lty\) 和 \(czx\) 到最后一个点的较大时间。
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<map>
#include<algorithm>
#define N 100010
#define int long long
using namespace std;
typedef pair<int,int> P;
int n,m,s,e,T;
struct node
{
int to,cost;
node(int _to,int _cost)
{
to=_to,cost=_cost;
}
};
struct path
{
int t,x; //czx在t时间到x
};
vector<node>G[N];
int dis[N];
priority_queue <P,vector<P>,greater<P> > que;
path a[N];
int read() //快读
{
int x=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
void dijkstra(int s) //dijkstra堆优化
{
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
que.push(P(0,s));
while(!que.empty())
{
P p=que.top();
que.pop();
int u=p.second;
if(p.first>dis[u]) continue;
for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i].to,w=G[u][i].cost;
if(dis[u]+w<dis[v])
{
dis[v]=dis[u]+w;
que.push(P(dis[v],v));
}
}
}
return;
}
bool cmp(path x,path y)
{
return x.t<y.t;
}
signed main()
{
n=read(),m=read(),s=read(),e=read();
for(int i=1; i<=m; i++)
{
int x=read(),y=read(),z=read();
G[x].push_back(node(y,z));
G[y].push_back(node(x,z));
}
dijkstra(s);
T=read();
for(int i=1; i<=T; i++)
a[i].t=read(),a[i].x=read();
sort(a+1,a+1+T,cmp); //按时间从小到大排序
a[++T]=(path){0,e}; //注意这里要把起点加进去
for(int i=1; i<=T; i++)
{
if(dis[a[i].x]<a[i+1].t)
{
printf("%lld\n",max(dis[a[i].x],a[i].t)); //输出后到的人的时间
return 0;
}
}
printf("%lld\n",max(dis[a[T].x],a[T].t));
return 0;
}
$$A\ drop\ of\ tear\ blurs\ memories\ of\ the\ past.$$