题目大意:n个点m条边,从1走到n需要多少代价?(边的代价为点数*距离)

最短路问题,只是需要记录每个点的深度,更新距离是需要用到。

每个点都有n种深度,很难确定SPFA的队列开多大,故用优先队列,当点n出队时,最小代价就出来了,因为后面的代价只会越来越大。

#include <bits/stdc++.h>
#define N 1005
#define LL long long
using namespace std;
LL n, m, i, j, k, a, b, c, v, s, mp[N][N], h[N];
struct AB{
    LL a, b, c, n;
} d[N*20];
struct AS{
    LL a, s, v;
    bool operator < (const AS &A) const{
        if(s != A.s) return s > A.s;
        return v > A.v;
    }
} t;
priority_queue <AS> q;
int main(){
    scanf("%lld%lld", &n, &m);
    for(i=1; i<=m; i++){
        scanf("%lld%lld%lld", &a, &b, &c);
        d[i].a = a, d[i].b = b, d[i].c = c;
        d[i].n = h[a], h[a] = i;
    }
    memset(mp, 9, sizeof(mp));
    q.push((AS){1, mp[1][1]=0, 1});
    while(q.size()){
        t = q.top(), q.pop();
        a = t.a, s = t.s, v = t.v;
        if(a == n) break;
        if(v > n || s>mp[a][v]) continue;
        for(i=h[a]; i; i=d[i].n){
            b = d[i].b, c = d[i].c;
            if(s+v*c < mp[b][v+1]){
                mp[b][v+1] = s + v*c;
                q.push((AS){b, mp[b][v+1], v+1});
            }
        }
    }
    printf("%lld\n", s);
    return 0;
}
#include <bits/stdc++.h>
#define N 1005
#define LL long long
using namespace std;
LL mp[N][N], v, s, ans=1e18;
LL n, m, i, j, k, a, b, c, h[N];
struct AB{
    LL a, b, c, n;
} d[N*20], q[N*400];
int main(){
    scanf("%lld%lld", &n, &m);
    for(i=1; i<=m; i++){
        scanf("%lld%lld%lld", &a, &b, &c);
        d[i].a = a, d[i].b = b, d[i].c = c;
        d[i].n = h[a], h[a] = i;
    }
    memset(mp, 9, sizeof(mp));
    q[1] = (AB){1, 1, mp[1][1]=0};
    for(i=j=1; i<=j; i++){
        a = q[i].a, s = q[i].c, v = q[i].b;
        if(j > n*400) break;
        for(k=h[a]; k; k=d[k].n){
            b = d[k].b, c = d[k].c;
            if(v<n && s+v*c < mp[b][v+1]){
                mp[b][v+1] = s + v*c;
                q[++j] = (AB){b, v+1, mp[b][v+1]};
            }
        }
    }
    for(i=1; i<=n; i++) ans = min(ans, mp[n][i]);
    printf("%lld\n", ans);
    return 0;
}

深搜部分分:

#include <bits/stdc++.h>
#define N 1005
#define LL long long
using namespace std;
LL mp[N][N], v, s, ans=1e18;
LL n, m, i, j, k, a, b, c, h[N];
struct AB{
    LL a, b, c, n;
} d[N*20];
void dfs(LL a, LL s, LL v){
    int b, c, i;
    if(a == n){
        ans = min(ans, s);
        return;
    }
    if(s >= mp[a][v]) return;
    mp[a][v] = s;
    for(i=1; i<v; i++){
        if(mp[a][i] < s) return;
    }
    for(i=h[a]; i; i=d[i].n){
        b = d[i].b, c = d[i].c;
        dfs(b, s+c*v, v+1);
    }
}
int main(){
    scanf("%lld%lld", &n, &m);
    for(i=1; i<=m; i++){
        scanf("%lld%lld%lld", &a, &b, &c);
        d[i].a = a, d[i].b = b, d[i].c = c;
        d[i].n = h[a], h[a] = i;
    }
    memset(mp, 9, sizeof(mp));
    dfs(1, 0, 1);
    printf("%lld\n", ans);
    return 0;
}