CF1941G 题解
思路
我们可以把问题转化一下:设每辆地铁都有一个固定车站 ,若想在 车站上车,就相当于是走过了一条 的边,若想在 车站下车,就相当于走过一条 的边。然后跑一遍最短路就好了,因为边权只有 ,所以也可以用双端队列优化。
代码
# 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;
}

浙公网安备 33010602011771号