洛谷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;
}
posted @ 2020-06-14 19:38  Acestar  阅读(138)  评论(0编辑  收藏  举报