【最短路/拆点】ACwing176

传送门

把每个点拆成100个点,分别表示到这个点的时候油量剩余的状态。跑最短路即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 233;
int p[maxn], val[maxn], e[maxn], pre[maxn], h[maxn], cnt;
void add(int u, int v, int w)
{
    e[cnt] = v; val[cnt] = w; pre[cnt] = h[u]; h[u] = cnt++;
}
struct Ver{
    int a, b, c;
    bool operator<(const Ver &W)const 
    {
        return c > W.c;
    }
};
int dis[1010][110];
bool vis[1010][110];
int dijkstra(int cost, int start, int end)
{
    memset(dis, 0x3f, sizeof dis);
    memset(vis,0, sizeof vis);
    priority_queue<Ver> pq;
    pq.push({start, 0, 0});
    dis[start][0] = 0;
    while(pq.size())
    {
        Ver t = pq.top(); pq.pop();
        if(t.a == end) return t.c;
        if(vis[t.a][t.b]) continue;
        vis[t.a][t.b] = 1;
        if(t.b < cost)
        {
            if(dis[t.a][t.b + 1] > t.c + p[t.a])
            {
                dis[t.a][t.b + 1] = t.c + p[t.a];
                pq.push({t.a, t.b + 1, t.c + p[t.a]});
            }
        }
        for(int i = h[t.a]; ~i; i = pre[i])
        {
            int y = e[i];
            if(t.b - val[i] >= 0)
            {
                if(dis[y][t.b - val[i]] > t.c)
                {
                    dis[y][t.b - val[i]] = t.c;
                    pq.push({y, t.b - val[i], t.c});
                }
            }
        }
    }
    return -1;
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);
    for(int i = 1; i <= n; i++) scanf("%d", &p[i]);
    for(int i = 1; i <= m; i++)
    {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        u++, v++;
        add(u, v, w); add(v, u, w);
    } 
    int T; scanf("%d", &T);
    while(T--)
    {
        int C, start, end;
        scanf("%d%d%d", &C, &start, &end);
        start++, end++;
        int ans = dijkstra(C, start, end);
        if(~ans) cout << ans << endl;
        else cout << "impossible" << endl;
    }
}

发表评论

邮箱地址不会被公开。 必填项已用*标注