2020 Multi-University Training Contest 4 1004- Deliver the Cake
链接
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;
}
————————————————
心里有光,哪儿都美
心里有光,哪儿都美