• BZOJ 1003: [ZJOI2006]物流运输trans SPFA+DP


    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1003

    题解:

    dp就好,令dp[i]表示第i天的答案,那么dp[i]=min{Cost(1,i),Cost(j+1,i)+dp[j]+K},其中Cost(i,j)表示从i到j都用同一种方案。这种dp和划分问题很类似。

    代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cstdio>
    #include<climits>
    #define INF 0x3f3f3f3f
    #define MAX_M 220
    #define MAX_N 1110
    using namespace std;
    
    int N,M,K,E;
    
    int dp[MAX_N];
    int d[MAX_M];
    
    queue<int> que;
    bool inQue[MAX_M];
    
    struct edge {
    public:
        int to, cost;
    
        edge(int t, int c) : to(t), cost(c) { }
    
        edge() { }
    };
    
    vector<edge> G[MAX_M];
    bool used[MAX_M];
    
    vector<int> days[MAX_N];
    
    int spfa() {
        while (que.size())que.pop();
        memset(inQue, 0, sizeof(inQue));
        fill(d, d + M + 1, INF);
        que.push(1);
        inQue[1] = 1;
        d[1] = 0;
        while (que.size()) {
            int u = que.front();
            que.pop();
            inQue[u]=0;
            for (int i = 0; i < G[u].size(); i++) {
                int v = G[u][i].to, c = G[u][i].cost;
                if (d[v] > d[u] + c && (!used[v])) {
                    d[v] = d[u] + c;
                    if (!inQue[v]) {
                        inQue[v] = 1;
                        que.push(v);
                    }
                }
            }
        }
        return d[M];
    }
    
    int COST(int i,int j) {
        memset(used, 0, sizeof(used));
        for (int k = i; k <= j; k++)
            for (int t = 0; t < days[k].size(); t++)
                used[days[k][t]] = 1;
        int tmp=spfa();
        if(tmp==INF)return INF;
        return (j - i + 1) * tmp;
    }
    
    int main() {
        //freopen("1003.in", "r", stdin);
        //freopen("1003.out", "w", stdout);
        scanf("%d%d%d%d", &N, &M, &K, &E);
        for (int i = 0; i < E; i++) {
            int u, v, c;
            scanf("%d%d%d", &u, &v, &c);
            G[u].push_back(edge(v, c));
            G[v].push_back(edge(u, c));
        }
        int D;
        scanf("%d",&D);
        while (D--) {
            int P, a, b;
            scanf("%d%d%d", &P, &a, &b);
            for (int i = a; i <= b; i++)days[i].push_back(P);
        }
        for (int i = 1; i <= N; i++) {
            dp[i] = COST(1,i);
            for (int j = 1; j < i; j++)
                dp[i] = min(dp[i], COST(j + 1, i) + dp[j] + K);
        }
        printf("%d
    ", dp[N]);
        return 0;
    }
  • 相关阅读:
    CPP STL学习笔记
    CPP 设计模式学习
    blackarch 安装指南
    通过 Http 请求获取 GitHub 文件内容
    实践
    升级
    部署-MySql 之Linux篇
    数据库
    RxJs
    Vue
  • 原文地址:https://www.cnblogs.com/HarryGuo2012/p/4845978.html
Copyright © 2020-2023  润新知