M - Walking Plan HDU - 6331

Posted lordxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了M - Walking Plan HDU - 6331相关的知识,希望对你有一定的参考价值。

分块+floyd
令dp[i][j][k]表示i到j恰好k条路经的最小权值。那么就有:dp[i][j][k]=min{dp[i][p][k-1]+dp[p][j][1]}我们可以预处理出前100条路径的dp值。然后考虑大范围转移,对dp[i][j][100]做一次floyd转移到200,再做一次转移到300,以此类推。
就可以求得,从j到j恰好k条路径的最小权值。
题目要求至少k条路径。那么对于小范围1~100的dp,我们从大往小,取min值,便可以表示从i到j至少k条路经的最小权值。对于大范围,dp[i][j][k*100],因为1~100的值我们已经更新过了,所以使用1~100来更新每一个k*100,便可以表示,至少k*100条路经,但少于(k+1)*100条路径的最小权值。查询的时候优先查询100的倍数,剩下的值通过1~100补全。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
    char ch = getchar(); ll x = 0, f = 1;
    while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int T;
int n, m, q;
const int mod = 1e9 + 7;
struct mat {
    int a[55][55];
    int n;
    void init(int n)
    {
        this->n = n;
        upd(i, 0, n)upd(j, 0, n)a[i][j] = mod;
    }
}dp_sm[105], dp_big[105];
mat floyd(mat dp1, mat dp2, mat dp3)
{
    mat res; res.init(n);
    int len = dp1.n;
    upd(i, 1, len)upd(j, 1, len)res.a[i][j] = min(res.a[i][j], dp3.a[i][j]);
    upd(k, 1, len)
    {
        upd(i, 1, len)
        {
            upd(j, 1, len)
            {
                if (dp1.a[i][k] == mod || dp2.a[k][j] == mod)continue;
                res.a[i][j] = min(res.a[i][j], dp1.a[i][k] + dp2.a[k][j]);
            }
        }
    }
    return res;
}
int main()
{
    T = read();
    while (T--)
    {
        n = read(), m = read();
        int u, v; int w;
        upd(i, 0, 100)dp_sm[i].init(n), dp_big[i].init(n);
        upd(i, 0, n)dp_sm[0].a[i][i] = dp_big[0].a[i][i] = 0;
        upd(i, 1, m)
        {
            u = read(), v = read(), w = read();
            dp_sm[1].a[u][v] = min(dp_sm[1].a[u][v], w);
        }
        upd(i, 0, 100)
        {
            dp_sm[i + 1] = floyd(dp_sm[1], dp_sm[i], dp_sm[i + 1]);
        }
        //upd(i, 1, n) { upd(j, 1, n) { printf("%d ", dp_sm[1].a[i][j]); }cout << endl; }
        dp_big[1] = dp_sm[100];
        upd(i, 0, 100)
        {
            dp_big[i + 1] = floyd(dp_big[1], dp_big[i], dp_big[i + 1]);
        }
        dwd(k, 99, 1)
        {
            upd(i, 1, n)upd(j, 1, n)dp_sm[k].a[i][j] = min(dp_sm[k + 1].a[i][j], dp_sm[k].a[i][j]);//反向取,表示至少
        }
        //upd(i, 1, n) { upd(j, 1, n) { printf("%lld ", dp_sm[1].a[i][j]); }cout << endl; }
        upd(i, 1, 100)
        {
            dp_big[i] = floyd(dp_big[i], dp_sm[1], dp_big[i]);
        }
        q = read();
        while (q--)
        {
            u = read(), v = read(), w = read();
            //cout << "*" << endl;
            int md = w % 100;
            int quan = w / 100;
            int ans = mod;
            //  upd(i, 1, n) { upd(j, 1, n) { printf("%lld ", dp_sm[1].a[i][j]); }cout << endl; }
            upd(k, 1, n)
            {
                //cout <<"k"<<k<<" "<< dp_sm[md].a[k][v] << endl;
                ans = min(ans, dp_big[quan].a[u][k] + dp_sm[md].a[k][v]);
            }
            if (ans == mod)printf("-1
");
            else printf("%d
", ans);
        }
    }
    return 0;
}

以上是关于M - Walking Plan HDU - 6331的主要内容,如果未能解决你的问题,请参考以下文章

2018HDU多校训练-3-Problem M. Walking Plan

POJ 3162 Walking Race 树形dp 优先队列

POJ3162 Walking Race(树形DP+尺取法+单调队列)

hdu 5290 Bombing plan

HDU-5540 Secrete Master Plan

CF 1036 B Diagonal Walking v.2 —— 思路