【洛谷 4880】抓住czx
题目背景
蒟蒻ltylty出了一道题,但是由于太弱了,所以希望喜欢鸽子的czxczx来帮他写一个stdstd。由于czxczx又放鸽子去了,所以没有写stdstd。蒟蒻ltylty觉得受到了学长的鄙视,所以决定去czxczx放鸽子的地方找他。
题目描述
czxczx放鸽子的地方是一个公园,公园珂以看作是由nn个点mm条边组成的无向图(保证无自环),ltylty将从公园的入口(bb号节点)进去寻找czxczx,czxczx刚开始的位置为ee,而czxczx会在a_iai个单位时间时变化位置到第xx个节点去,在此之前ltylty已经知道了czxczx的具体位置和接下来他位置的变化方案,蒟蒻ltylty现在想知道他至少需要花多少时间找到czxczx。
UPD:
保证图联通,czxczx最后会待在一个地方不动
输入格式
第一行四个整数nn,mm,bb,ee,bb和ee的意义如题面所示。
接下来mm行,每行三个整数x,y,zx,y,z,表示xx到yy之间有一条双向边,ltylty走这条边要花费zz的时间。
第m+1m+1行一个整数TT,表示czxczx位置变化的次数。
接下来TT行,每行两个整数a_iai和xx,表示czxczx将在第a_iai个单位时间时移动到第xx个点上去。
输出格式
一个整数表示最短所需时间。
输入输出样例
6 9 1 6 1 2 1 1 3 3 1 4 4 2 3 2 3 6 6 4 5 6 2 5 9 3 5 7 5 6 2 3 10 3 8 5 9 2
9
说明/提示
**样例解释:**在开始的时候就直接走到22号节点,然后等到czxczx过来。总花费时间99个单位时间。
对于30%的数据,n<=100,m<=1000,T<=100n<=100,m<=1000,T<=100
对于另外30%的数据,T=0T=0
对于100%的数据,n<=10^5,m<=5\times10^5,T<=10^5n<=105,m<=5×105,T<=105
数据保证所有时间在intint范围内
注意:在任意一个czxczx开始移动的时间点,都是czxczx先瞬移,然后ltylty再行走,也就是说,ltylty不能在czxczx瞬移的时候到他瞬移前的点抓住他,但是ltylty可以在他瞬移到的点等着抓他。
题解:一道最短路,加上个简单的判断,不过因为数组大小的原因我wa了40个点
花好长时间才找到(气鼓鼓)
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> using namespace std; const int N=1000002; const int oo=0x3f3f3f3f; int Yao_Chen,n,m,b,E,x,y,z; struct node{ int next; int to; int val; }e[N]; struct data{ int pc; int ti; }a[N]; int cnt,head[N],dis[N]; bool vis[N]; void add(int x,int y,int z){ e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt; e[cnt].val=z; } void spfa(){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); queue <int> q; dis[b]=0; vis[b]=1; q.push(b); while(!q.empty()){ x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i;i=e[i].next){ y=e[i].to; if(dis[y]>dis[x]+e[i].val){ dis[y]=dis[x]+e[i].val; if(vis[y]==0) { vis[y]=1; q.push(y); } } } } } bool cmp(data p,data q) { return p.ti<q.ti; } int main(){ freopen("4880.in","r",stdin); freopen("4880.out","w",stdout); scanf("%d %d %d %d",&n,&m,&b,&E); a[0].ti=0; a[0].pc=E; for(int i=1;i<=m;i++){ scanf("%d %d %d",&x,&y,&z); add(x,y,z); add(y,x,z); } spfa(); scanf("%d",&Yao_Chen); for(int i=1;i<=Yao_Chen;i++) scanf("%d %d",&a[i].ti,&a[i].pc); a[++Yao_Chen].ti=oo; a[Yao_Chen].pc=0; sort(a,a+Yao_Chen+1,cmp); for (int i=0;i<=Yao_Chen;i++){ if (dis[a[i].pc]<a[i+1].ti){ printf("%d\n",max(dis[a[i].pc],a[i].ti)); break; } } return 0; }