首页 > 其他分享 >城市定向

城市定向

时间:2022-10-01 16:33:54浏览次数:34  
标签:11 13 le int 城市 地铁 道路 定向

你正在筹划一场城市定向。你拥有一张包含 $n$ 个地点的城市地图,其中编号为 1 的为起点。地图上标明了所有选手能够通行的道路的信息,这样的道路一共有 $m$ 条,分为两种类型:

  • 普通道路。对于每条普通道路,地图上都会给出它连接的两个地点的编号 $u$, $v$,以及选手通过它需要花费的时间 $w$。每条普通道路在任意时刻都可以双向通行。
  • 地铁线路。对于每条地铁线路,地图上都会给出它连接的两个相邻的站点编号 $u$, $v$,始发时刻 $t_0$, 运行时间间隔 $t$,以及从站点 $u$ 出发抵达站点 $v$ 所需的时间 $w$。注意,地铁的运行时间间隔为 $t$ 代表只有在 $t_0, t_0+t, t_0+2t, t_0+3t, ...$ 时刻会有地铁进站,在地铁进站时刻 $t'$ 及以前到达站点 $u$ 的选手都能够在 $t'$ 时刻搭乘上地铁,上地铁所花费的时间忽略不计。

现在,筹备组的你为了规划合适的线路,需要为任意一个地点 $i$ 计算出:0 时刻从起点出发,到达地点 $i$ 的最早时刻。

输入

第一行包含两个正整数 $n,m$。分别表示地点个数和道路条数。

接下来 $m$ 行。每行描述一条道路。

道路的描述有两种格式:

  • 0 u v w :普通道路,$u,v,w$ 的含义同题目描述。
  • 1 u v t0 t w :地铁线路,$u,v,t_0,t,w$ 的含义同题目描述。

保证 $1 \le u,v \le n$, 保证从起点出发能到达所有的地点。

输出

一行 $n$ 个数,第 $i$ 个数表示在 0 时刻从起点出发,到达地点 $i$ 的最早时刻。

输入样例1

4 6
1 1 2 1 5 1
1 2 3 4 2 1
0 1 4 5
1 1 4 2 5 1
0 4 2 5
0 4 1 1

输出样例1

0 2 5 1

输入样例2

5 20
0 1 2 35
0 1 5 27
1 5 4 13 9 26
1 4 3 3 13 35
0 3 1 3
0 4 2 13
1 1 1 2 3 11
1 3 4 11 19 11
0 3 4 11
1 1 3 16 1 11
1 3 5 11 18 31
1 1 5 1 1 13
0 4 5 10
1 3 2 5 4 30
1 1 1 1 16 41
1 1 5 3 14 39
0 4 2 31
1 3 3 13 9 29
0 2 3 14
1 5 1 2 16 13

输出样例2

0 17 3 14 14

数据规模

对于 $50\%$ 的数据,$n,m \le 1000$。

另有 $20\%$ 的数据,保证只有普通道路。

对于 $100%$ 的数据,$1 \le n,m \le 5\times 10^5$ , $0 \le t_0, t, w \le 10^9$, $t>0$ 。

时间限制:1000 ms

内存限制:512 MB

怎么考虑呢?首先发现无论是普通道路还是地铁道路,所耗的代价不会变小,所以果断dijkstra。

普通道路其实很好去迭代。那么地铁道路我们需要通过与 \(t\) 的模数求出下一次地铁到达的时间,然后再加上 \(w\) 就行了。

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
typedef long long LL;
int n,m,hd[N],e_num,w,op,t0,t,vis[N],u,v;
LL dis[N];
struct edge{
	int v,nxt,op,t0,t,w;
}e[N<<1];
struct node{
	int v;
	LL w;
	bool operator<(const node&n)const{
		return w>n.w;
	}
};
priority_queue<node>q; 
void add_edge(int op,int t0,int t,int u,int v,int w)
{
	e[++e_num]=(edge){v,hd[u],op,t0,t,w};
	hd[u]=e_num;
}
LL dist(LL u,int ed)
{
	if(!e[ed].op)
		return u+e[ed].w;
	if(u<e[ed].t0)
		return e[ed].t0+e[ed].w;
	if((u-e[ed].t0)%e[ed].t==0)
		return u+e[ed].w;
	return (u-e[ed].t0+e[ed].t-1)/e[ed].t*e[ed].t+e[ed].t0+e[ed].w;
}
void dijkstra()
{
	memset(dis,0x7f,sizeof(dis));
	dis[1]=0;
	q.push((node){1,0});
	while(!q.empty())
	{
		int k=q.top().v;
		q.pop();
		if(vis[k])
			continue;
		vis[k]=1;
		for(int i=hd[k];i;i=e[i].nxt)
		{
			if(dist(dis[k],i)<dis[e[i].v])
			{
				dis[e[i].v]=dist(dis[k],i);
				q.push((node){e[i].v,dis[e[i].v]});
			}
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&op);
		if(!op)
		{
			scanf("%d%d%d",&u,&v,&w);
			add_edge(0,0,0,u,v,w);
			add_edge(0,0,0,v,u,w);
		}
		else
		{
			scanf("%d%d%d%d%d",&u,&v,&t0,&t,&w);
			add_edge(1,t0,t,u,v,w);
		}
	}
	dijkstra();
	for(int i=1;i<=n;i++)
		printf("%lld ",dis[i]);
	return 0;
}

标签:11,13,le,int,城市,地铁,道路,定向
From: https://www.cnblogs.com/mekoszc/p/16747352.html

相关文章