CF1941G 题解

思路

我们可以把问题转化一下:设每辆地铁都有一个固定车站 xx,若想在 yy 车站上车,就相当于是走过了一条 yx,w=1y\to x,w=1 的边,若想在 yy 车站下车,就相当于走过一条 xy,w=0x\to y,w=0 的边。然后跑一遍最短路就好了,因为边权只有 0,10,1,所以也可以用双端队列优化。

代码

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
const int inf = 1e9;
int t, n, m, x, y, c, d[400005];
vector <pii> v[400005];
deque <int> q;
bitset <400005> vis;
map <int, int> r;
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> t;
	while (t --) {
		cin >> n >> m;
		x = n + m;
		r.clear ();
		for (int i = 1; i <= x; ++ i)
			v[i].clear (), vis[i] = 0, d[i] = inf;
		while (m --) {
			cin >> x >> y >> c;
			if (! r[c])
				r[c] = ++ n;
			c = r[c];
			v[x].push_back ({c, 1});
			v[y].push_back ({c, 1});
			v[c].push_back ({x, 0});
			v[c].push_back ({y, 0});
		}
		cin >> x >> y;
		d[x] = 0;
		q.push_back (x);
		while (! q.empty ()) {
			x = q.front ();
			q.pop_front ();
			if (x == y) {
				while (! q.empty ())
					q.pop_back ();
				cout << d[x] << '\n';
				break ;
			}
			if (vis[x])
				continue ;
			vis[x] = 1;
			for (pii& i : v[x])
				if (d[x] + i.second < d[i.first])
					if (i.second)
						d[i.first] = d[x] + 1, q.push_back (i.first);
					else
						d[i.first] = d[x], q.push_front (i.first);
		}
	}
	return 0;
}
posted @   sz_jinzikai  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示