2020 Multi-University Training Contest 4 1004- Deliver the Cake
阿新 • • 發佈:2020-07-30
連結
http://acm.hdu.edu.cn/showproblem.php?pid=6805
題意
n個點,每個點有屬性,L,R或M
m條邊,連線兩點
現從s走到t,要求最短路
有一附加條件,L點用左手,R點用右手,M點均可,任意地方均可換手,換手時間為x
思路
裸的最短路,LR邊的邊權要多加x,LM和RM連邊時將M拆成L點或R點去連,MM連邊時將M拆成LL和RR去連
然後跑最短路就好了,因為邊陣列開小了所以一直T
程式碼
#include <bits/stdc++.h> // #define inf 0x7f7f7f7f #define ms(a) memset(a, 0, sizeof(a)) #define repu(i, a, b) for (int i = a; i < b; i++) #define repd(i, a, b) for (int i = a; i > b; i--) using namespace std; typedef long long ll; typedef long double ld; const int M = int(1e5) * 2 + 5; const int mod = int(1e9) + 7; const ll inf = ll(1e18); struct edge { ll to; ll w; ll next; }; edge edges[M * 3]; int head[M]; int _cnt; void add(ll u, ll v, ll w) { edges[_cnt].to = v; edges[_cnt].w = w; edges[_cnt].next = head[u]; head[u] = _cnt++; edges[_cnt].to = u; edges[_cnt].w = w; edges[_cnt].next = head[v]; head[v] = _cnt++; } void init() { _cnt = 0; memset(head, -1, sizeof(head)); } struct node { ll v; ll cost; node(ll _v = 0, ll _c = 0) : v(_v), cost(_c) {} bool operator<(const node& b) const { return cost > b.cost; } }; ll dis[M]; bool vis[M]; void dijkstra(ll n, ll start) { memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) dis[i] = inf; dis[start] = 0; priority_queue<node> pq; pq.push(node(start, 0)); node tem; while (!pq.empty()) { tem = pq.top(); pq.pop(); ll u = tem.v; if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; ~i; i = edges[i].next) { ll v = edges[i].to; if (dis[v] > dis[u] + edges[i].w) { dis[v] = dis[u] + edges[i].w; pq.push(node(v, dis[v])); } } } } int hand[M]; int main() { ios::sync_with_stdio(false); cin.tie(0); int t; cin >> t; while (t--) { init(); ms(hand); ll n, m, s, t, x; cin >> n >> m >> s >> t >> x; string str; cin >> str; int tot = 0; repu(i, 0, str.size()) { if (str[i] == 'L') { hand[i + 1] = 1; } else if (str[i] == 'R') { hand[i + 1] = 2; } else { hand[i + 1] = 0; if ((i + 1) != s && (i + 1) != t) { add(i + 1, i + n + 1, x); } else { add(i + 1, i + 1 + n, 0); } } } repu(i, 0, m) { ll u, v, w; cin >> u >> v >> w; if (hand[u] == hand[v]) { add(u, v, w); if (!hand[u]) { add(u + n, v + n, w); } } else { if (!hand[u]) { if (hand[v] == 1) { add(u, v, w); } else { add(u + n, v, w); } } else if (!hand[v]) { if (hand[u] == 1) { add(u, v, w); } else { add(u, v + n, w); } } else { add(u, v, w + x); } } } dijkstra(n * 2 + 1, s); cout << dis[t] << endl; } return 0; }