最短路20pts,求调
查看原帖
最短路20pts,求调
411141
alpharchmage楼主2023/10/4 16:57
#include<bits/stdc++.h>
using namespace std;
int n = 0,h = 0,cnt = 0;
int head[300001];
int dis[300001];
bool vis[300001];
int nowx = 0,nowy = 0,nowh = 0;
struct Line{
	int l;
	int r;
	int h;
}line[300001];
struct node{
	int to;
	int val;
	int next;
}edge[4000001];
struct Point{
	int x;
	int y;
	int id;
};
struct Path{
	int id;
	int dis;
};
queue<Point> q;
bool operator < (const Path &x , const Path &y)
{
	return x.dis < y.dis;
}
bool operator > (const Path &x , const Path &y)
{
	return x.dis > y.dis;
}
priority_queue<Path , vector<Path> , greater<Path> > path;
void new_line(int a , int b , int c)
{
	edge[++ cnt].to = b;
	edge[cnt].val = c;
	edge[cnt].next = head[a];
	head[a] = cnt;
	return;
}
bool cmp(Line x , Line y)
{
	if(x.h == y.h)
	{
		return x.l == y.l ? x.r < y.r : x.l < y.l; 
	}
	return x.h > y.h;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin >> n >> h;
	cin >> nowx >> nowy;
	for(int i = 1;i <= n;++ i)
	{
		cin >> line[i].h >> line[i].l >> line[i].r;
	}
	sort(line + 1 , line + n + 1 , cmp);
	q.push({nowx , nowy , 0});
	while(!q.empty())
	{
		Point now = q.front();
		q.pop();
		int bound = max(0 , now.y - h);
		int l = 1 , r = n , res = 0;
		while(l <= r)
		{
			int mid = l + (r - l) / 2;
			if(line[mid].h >= bound)
			{
				res = mid;
				l = mid + 1;
			} 
			else
			{
				r = mid - 1;
			}
		}
		int belong = (now.id + 1) / 2;
		bool flag = 1;
		for(int i = belong + 1;i <= res;++ i)
		{
			if(line[i].l <= now.x && now.x <= line[i].r)
			{
				flag = 0;
				new_line(now.id , i * 2 - 1 , now.x - line[i].l);
				new_line(now.id , i * 2 , line[i].r - now.x);
				q.push(Point{line[i].l , line[i].h , i * 2 - 1});
				q.push(Point{line[i].r , line[i].h , i * 2});
			}
		}
		if(bound == 0 && flag)
		{
			new_line(now.id , 2 * n + 1 , 0);
		}
	}
	memset(dis , 0x3f , sizeof dis);
	dis[0] = 0;
	path.push({0 , 0});
	while(!path.empty())
	{
		int x = path.top().id;
		path.pop();
		if(vis[x])
		{
			continue;
		}
		vis[x] = true;
		for(int e = head[x];e;e = edge[e].next)
		{
			int to = edge[e].to;
			if(dis[to] > dis[x] + edge[e].val)
			{
				dis[to] = dis[x] + edge[e].val;
				path.push({to , dis[to]});
			}
		}
	}
	cout << nowy + dis[2 * n + 1] << endl;
	return 0; 
 } 
2023/10/4 16:57
加载中...