最短路+背包 ACdream群赛题目

题目链接点这儿

先跑个最短路,然后在最短路的基础上跑个多重背包。

开始看错了,以为是分组背包 囧

#include <bits/stdc++.h>
 
#define up(i, lower, upper) for(int i = lower; i < upper; i++)
#define down(i, lower, upper) for(int i = upper-1; i >= lower; i--)
 
using namespace std;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<pii> vpii;
typedef long long ll;
typedef unsigned long long ull;
 
const double pi = acos(-1);
const double eps = 1.0e-9;
 
template<class T>
 
inline bool read(T &n){
    T x = 0, tmp = 1; char c = getchar();
    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
    if(c == EOF) return false;
    if(c == '-') c = getchar(), tmp = -1;
    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();
    n = x*tmp;
    return true;
}
 
template <class T>
inline void write(T n) {
    if(n < 0) {
        putchar('-');
        n = -n;
    }
    int len = 0,data[20];
    while(n) {
        data[len++] = n%10;
        n /= 10;
    }
    if(!len) data[len++] = 0;
    while(len--) putchar(data[len]+48);
}
 
///---------------------------------------------------------
const int maxn = 110 ;
const int maxT = 1100 ;
 
int n , m , T ;
int x[maxn] , w[maxn] , t[maxn] , dis[maxn];
int atlas[maxn][maxn] ;
ll f[maxT] ;
 
int main() {
    scanf("%d%d%d",&n,&m,&T) ;
    for(int i = 1 ; i <= n ; i++) read(x[i]), read(w[i]), read(t[i]);
    memset(atlas , 0x3f , sizeof(atlas)) ;
    for(int i = 0 ; i <= n ; i++) atlas[i][i] = 0 ;
    for(int i = 0 ; i < m ; i++) {
        int xi , yi , bi;
        read(xi), read(yi), read(bi);
        atlas[xi][yi] = min(atlas[xi][yi] , bi) ;
    }
    for(int k = 0 ; k <= n ; k++)
    for(int i = 0 ; i <= n ; i++)
    for(int j = 0 ; j <= n ; j++)
    atlas[i][j] = min(atlas[i][j] , atlas[i][k] + atlas[k][j]) ;
    for(int i = 0 ; i <= n ; i++) dis[i] = atlas[0][i] ;
    for(int i = 1 ; i <= n ; i++)
        for(int ti = T ; ti >= 0 ; ti--) {
            int j = ti + dis[i] ;
            for(int k = 1 ; k <= x[i] ; k++) {
                if(j + k*t[i] > T) break ;
                f[j+k*t[i]] = max(f[j+k*t[i]] , f[ti]+k*w[i]) ;
            }
        }
    write(f[T]); puts("");
    return 0 ;
}


你可能感兴趣的:(算法,ACM,最短路,背包)