题目大意
给你一些交通方式和站点,不同的交通方式碳排放不一样,问从起点到终点距离不超过B的路径中最少的碳排放是多少。
解题思路
最短路和dp的混合题,设dp[u][j]表示到点u路径长度为j的最少碳排放,在最短路进行松弛的过程中进行状态转移就行了。
代码
const int maxn = 2e5+10;
int xs, ys, xd, yd, B, c[maxn], t, n;
P ct[maxn];
vector<P> e[maxn];
struct E {
ll w, dis; int to;
};
vector<E> e2[maxn];
ll dp[2000][110]; bool vis[2000];
ll solve(int i, int j) {
return ceil(sqrt(1LL*(ct[i].x-ct[j].x)*(ct[i].x-ct[j].x) +
1LL*(ct[i].y-ct[j].y)*(ct[i].y-ct[j].y)));
}
void spfa() {
memset(dp, 0x3f, sizeof(dp));
dp[n-2][0] = 0;
queue<int> q; q.push(n-2);
while(!q.empty()) {
int u = q.front(); q.pop();
vis[u] = 0;
for (auto v : e2[u]) {
for (int j = B; j>=v.dis; --j)
if (dp[v.to][j] > dp[u][j-v.dis]+v.w) {
dp[v.to][j] = dp[u][j-v.dis]+v.w;
if (!vis[v.to]) q.push(v.to), vis[v.to] = 1;
}
}
}
}
int main() {
cin >> xs >> ys >> xd >> yd;
cin >> B;
cin >> c[0];
cin >> t;
for (int i = 1; i<=t; ++i) cin >> c[i];
cin >> n;
for (int i = 0, x, y, l; i<n; ++i) {
scanf("%d%d%d", &x, &y, &l);
ct[i] = {x, y};
while(l--) {
scanf("%d%d", &x, &y);
e[i].push_back({x, y});
}
}
for (int i = 0; i<n; ++i)
for (auto v : e[i]) {
ll dis = solve(i, v.x);
e2[i].push_back({c[v.y]*dis, dis, v.x});
e2[v.x].push_back({c[v.y]*dis, dis, i});
}
ct[n++] = {xs, ys};
ct[n++] = {xd, yd};
for (int i = 0; i<n; ++i) {
ll dis = solve(i, n-1);
e2[i].push_back({c[0]*dis, dis, n-1});
e2[n-1].push_back({c[0]*dis, dis, i});
}
for (int i = 0; i<n; ++i) {
ll dis = solve(i, n-2);
e2[i].push_back({c[0]*dis, dis, n-2});
e2[n-2].push_back({c[0]*dis, dis, i});
}
spfa();
ll minn = 0x3f3f3f3f3f3f3f3f;
for (int i = 0; i<=B; ++i) minn = min(minn, dp[n-1][i]);
if (minn==0x3f3f3f3f3f3f3f3f) minn = -1;
cout << minn << endl;
return 0;
}