1. 程式人生 > >HDU6331&&18多校3M Walking Plan 【分塊+DP】

HDU6331&&18多校3M Walking Plan 【分塊+DP】

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

Total Submission(s): 633    Accepted Submission(s): 229

 

Problem Description

There are n intersections in Bytetown, connected with m one way streets. Little Q likes sport walking very much, he plans to walk for q days. On the i-th day, Little Q plans to start walking at the si-th intersection, walk through at least ki streets and finally return to the ti-th intersection.
Little Q's smart phone will record his walking route. Compared to stay healthy, Little Q cares the statistics more. So he wants to minimize the total walking length of each day. Please write a program to help him find the best route.

 

Input

The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases.
In each test case, there are 2 integers n,m(2≤n≤50,1≤m≤10000) in the first line, denoting the number of intersections and one way streets.
In the next m lines, each line contains 3 integers ui,vi,wi(1≤ui,vi≤n,ui≠vi,1≤wi≤10000), denoting a one way street from the intersection ui to vi, and the length of it is wi.
Then in the next line, there is an integer q(1≤q≤100000), denoting the number of days.
In the next q lines, each line contains 3 integers si,ti,ki(1≤si,ti≤n,1≤ki≤10000), describing the walking plan.

題意:給定一個 n 個點,m 條邊的有向圖,q 次詢問 s 到 t 經過至 少 k 條邊的最短路。(2 ≤ n ≤ 50, 1 ≤ m, k ≤ 10000, 1 ≤ q ≤ 100000)

分析:比賽時沒有思路,後來看啦題解補啦。由於查詢次數和至少經過的邊數都比較大,如果提前預處理,複雜度是10000*50*50*50,很明顯會超時。每次單獨計算消耗時間更多。所以可以採用分塊的演算法來節省時間。此題的分塊是提前預處理出任意兩點經過至少100*i和i條邊的最小距離(i<=100),這個預處理過程可以用DP來完成。然後每次求解答案時,就可以在O(n)的時間內通過列舉中間點計算出來。(例於,要求1到n至少經過1234條邊的最小距離,求列舉點p,1經過至少1200條邊和p點到n至少經過34條邊的距離和的最小值)

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=110;
const int INF=0x3f3f3f3f;
int d[N][N][N],g[N][N][N],a[N][N],b[N][N]; //d陣列存任意兩點至少經過100*i條邊的最小值
                                           //g陣列存任意兩點至少經過i條邊的最小值
int main()
{
    int TA,n,m,T,u,v,x,y,z,num;
    scanf("%d",&TA);
    while(TA--)
    {
        scanf("%d%d",&n,&m);
        memset(g,0x3f,sizeof(g));
        memset(d,0x3f,sizeof(d));
        for(int i=1; i<=n; i++)
            g[0][i][i]=d[0][i][i]=0;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if(g[1][x][y]>z)
                g[1][x][y]=z;
        }
        for(int l=1; l<N; l++)
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    for(int k=1; k<=n; k++)
                        g[l][i][j]=min(g[l][i][j],g[l-1][i][k]+g[1][k][j]);


        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                d[1][i][j]=g[100][i][j];

        for(int l=1; l<N; l++)
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    for(int k=1; k<=n; k++)
                        d[l][i][j]=min(d[l][i][j],d[l-1][i][k]+d[1][k][j]);

        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                a[i][j]=i==j?0:g[1][i][j];

        for(int k=1; k<=n; k++)
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                    a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
        for(int l=0; l<N; l++)
        {

            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                {
                    b[i][j]=INF;
                    for(int k=1; k<=n; k++)
                        b[i][j]=min(b[i][j],d[l][i][k]+a[k][j]);

                    d[l][i][j]=b[i][j];
                }
        }
          
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&u,&v,&num);
            x=num/100;
            y=num%100;
            int ans=INF;
            for(int k=1; k<=n; k++)
            {
                ans=min(ans,g[y][u][k]+d[x][k][v]);
            }
            if(INF<=ans)ans=-1;
            printf("%d\n",ans);
        }
    }
}

相關推薦

HDU6331&&183M Walking Plan +DP

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Total Submission(s): 633    Accepted Submissi

HDU 6319&&183A Ascending Rating 單調佇列

Problem A. Ascending Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Total Submiss

HDU-63957 Sequence(除法+矩陣快速冪)

review lse %d sca code left define hdu fin Sequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others

HDU 6331 Walking Plan 動態規劃)

題意 給一個 nn 個節點 mm 條邊的有向圖,第 ii 條邊的兩個端點為 ui,viui,vi,邊的長度為 wiwi,qq 次詢問,每次詢問從節點 ss 到 tt 至少走過 kk 條路徑的最小距離。 輸入 第一行包含一個整數 T(1

BZOJ3509 [CodeChef] COUNTARI + fft

ace cos TE truct line while space 鏈接 左右 題目鏈接 BZOJ3509 題解 化一下式子,就是 \[2A[j] = A[i] + A[k]\] 所以我們對一個位置兩邊的數構成的生成函數相乘即可 但是由於這樣做是\(O(n^2logn)\)

洛谷p2801教主的魔法模板

給出一個數列,支援區間修改,區間查詢大於等於key的值個數,分塊模板加一個小二分。 詳情見程式碼。A指查詢(L到R大於x),M指修改(將L到R增加x) #include<bits/stdc++.h> #define in in() using namespace std; i

HDU 6327&&18訓練3I DP

Problem I. Random Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Total Submissio

hdu5816 7 Hearthstone組合計數+dp

題目大意: 牌堆有n張奧術牌,奧術牌可以再從牌堆摸兩張牌, m張傷害牌,傷害各為xi,初始從牌堆摸一張,問本回合能擊殺給定hp的對手的概率,結果用分數表示。(n+m<=20) 如果n

HDU 5732 2016Contest 1 Subway找樹的重心,判斷樹的同構

題目大意: 給定一棵樹,這兩棵樹肯定是同構的。 問你,第一棵樹的每個節點,可以對應第二個樹的那個節點。 顯然對應方法不唯一,SPJ來檢測結果正確。 方法: 首先找樹的重心, 樹的重心最多2個。 一個重心的情況很多,兩個重心的情況如圖: 有人說這個圖太對稱了……

牛客7C Bit Compression 搜尋優化

Bit Compression 時間限制:C/C++ 2秒,其他語言4秒 空間限制:C/C++ 262144K,其他語言524288K Special Judge, 64bit IO Format: %lld 題目描述 A binary string s of le

寒訓TaoTao要吃雞dp(未完成)

gpo 解釋 scanf div item 背包 -cp 並且 輸入 題目描述 Taotao的電腦帶不動絕地求生,所以taotao只能去玩pc版的荒野行動了, 和絕地求生一樣,遊戲人物本身可以攜帶一定重量m的物品,裝備背包 之後可以多攜帶h(h為0代表沒有裝備背包)重

c# 網絡卡 由網路介面卡名獲取網絡卡資訊,IP

c# 多網絡卡 由【網路介面卡名】獲取網絡卡資訊,IP 多網絡卡電腦中,網路介面卡的名字 多樣化! 專案中需要,根據網路介面卡 名字 獲取 單個網絡卡的IP: using System.Net.NetworkInformation;

P1282 米諾骨牌 01揹包DP

多米諾骨牌有上下2個方塊組成,每個方塊中有1~6個點。現有排成行的 上方塊中點數之和記為S1,下方塊中點數之和記為S2,它們的差為|S1-S2|。例如在圖8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2。每個多米諾骨牌可以旋轉180°,使得

Groovy Grails 教程 國際化語言配置方法教程Grails中文教程

Groovy Grails 教程 國際化多語言配置方法教程【Grails中文教程】 【原文連結:http://www.jsjtt.com/bianchengyuyan/groovy/2013-11-19/22.ht

狀壓DPpoj3254 Corn Fields

一行 cstring fields while state 條件 style 狀壓 () 題意: 一塊n*m的田,1表示這個地方可以種植,0代表這個地方不能種植。植物種植還必須滿足兩株植物不能相鄰(橫豎都不行)。問共有幾種種植方法,而且當什麽都不種時認為是一種方法。 解題思

狀壓dpCDOJ1608 暑假集訓

algo name pac 開始 技術分享 只需要 memset urn cnblogs 裸的狀壓的話,很顯然……但有一個強大的優化。 就是在枚舉決策的時候,固定第一個空位置。可以證明,這樣狀態數沒有減少,但是降低了很多重復訪問。 因為你在枚舉的時候,總是可以劃分為包含第

狀壓dp互不侵犯KING

git algorithm long long true 求解 格子 ble bool span 互不侵犯KING Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3866 Solved: 2264[Submit][Sta

狀壓dp送餐員

data etc 接下來 -s enter algorithm urn 我們 stream [odevs2800]送餐員 題目描述 Description 有一個送外賣的,他手上有n份訂單,他要把n份東西,分別送達n個不同的客戶的手上。n個不同的客戶分別在1~n

狀壓dpMost Powerful

last algorithm out 我只 res queue str nbsp digi [ZOJ3471]Most PowerfulTime Limit: 2 Seconds Memory Limit: 65536 KB Recently, research

打表bzoj 3758 數數

inpu 綜合 前綴和 lan 不能 art -1 esc ref 【題目描述】 Description 神犇最近閑來無事,於是就思考哲學,研究數字之美。在神犇看來,如果一個數的各位能夠被分成兩個集合,而且這兩個集合裏的數的和相等,那麽這個數就是優美的(具體原因就只有神犇才