gym102501A - Environment-Friendly Travel(最短路,dp)

题目链接

题目大意

  给你一些交通方式和站点,不同的交通方式碳排放不一样,问从起点到终点距离不超过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][110];
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][B] = 0;
    queue<P> q; q.push({n-2, B});
    while(!q.empty()) {
        int u = q.front().x; 
        int w = q.front().y;
        q.pop();
        vis[u][w] = 0;
        for (auto v : e2[u]) {
            if (w-v.dis>=0 && dp[v.to][w-v.dis] > dp[u][w]+v.w) {
                dp[v.to][w-v.dis] = dp[u][w]+v.w;
                if (!vis[v.to][w-v.dis]) q.push({v.to, w-v.dis}), vis[v.to][w-v.dis] = 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;
}
posted @ 2021-03-05 19:59  shuitiangong  阅读(86)  评论(0编辑  收藏  举报