hdu 5361 2015多校联合训练赛#6 最短路

In Touch

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 67    Accepted Submission(s): 11

Problem Description

There are n soda living in a straight line. soda are numbered by  from
left to right. The distance between two adjacent soda is 1 meter. Every soda has a teleporter. The teleporter of -th
soda can teleport to the soda whose distance between -th
soda is no less than  and
no larger than .
The cost to use -th
soda‘s teleporter is .

The -st
soda is their leader and he wants to know the minimum cost needed to reach -th
soda .

Input

There are multiple test cases. The first line of input contains an integer ,
indicating the number of test cases. For each test case:

The first line contains an integer  ,
the number of soda.

The second line contains  integers .
The third line contains  integers .
The fourth line contains  integers .

Output

For each case, output  integers
where -th
integer denotes the minimum cost needed to reach -th
soda. If -st
soda cannot reach -the
soda, you should just output -1.

Sample Input

1
5
2 0 0 0 1
3 1 1 0 5
1 1 1 1 1

Sample Output

0 2 1 1 -1

Hint

If you need a larger stack size,
please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.

Source

2015 Multi-University Training Contest 6

求最短路:把一个集合的点看做是一个点,这样就能够用djstra算法做了。然后因为每一个点最多标记一次最短路,用set维护一个点集合。

当最短路找到一个一个集合的时候,把这个集合里还存在的点都取出就可以。取出后。每一个点又能够去两个集合。

再向保存最短路的set里更新集合信息就可以。具体看代码。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
#define maxn 200007
#define ll long long

int lp[maxn],rp[maxn];
ll cosw[maxn];
ll dist[maxn];

set<int> haha;

struct Node{
    int id;
    ll cost;
};
bool operator < (Node a,Node b){
    if(a.cost == b.cost) return a.id < b.id;
    return a.cost < b.cost;
}

set<Node> mind;

int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i = 0;i < n; i++)
            scanf("%d",&lp[i]);
        for(int i = 0;i < n; i++)
            scanf("%d",&rp[i]);
        for(int i = 0;i < n; i++)
            scanf("%d",&cosw[i]);
        haha.clear();
        mind.clear();
        memset(dist,-1,sizeof(dist));
        dist[0] = 0;

        Node x,y;
        x.id = 0;
        x.cost = cosw[0];
        mind.insert(x);
        for(int i = 1;i < n; i++)
            haha.insert(i);

        set<int>::iterator it,it2;
        while(mind.size() > 0){
            x = *mind.begin();
            mind.erase(mind.begin());

            it = haha.lower_bound(x.id - rp[x.id]);
            while(it != haha.end()  && *it <= x.id - lp[x.id]){
                y.id = *it;
                y.cost = x.cost + cosw[y.id];
                dist[y.id] = x.cost;
                mind.insert(y);
                it2 = it++;
                haha.erase(it2);
            }

            it = haha.lower_bound(x.id + lp[x.id]);
            while(it != haha.end()  && *it <= x.id + rp[x.id]){
                y.id = *it;
                y.cost = x.cost + cosw[y.id];
                dist[y.id] = x.cost;
                mind.insert(y);
                it2 = it++;
                haha.erase(it2);
            }
        }
        for(int  i = 0;i < n; i++){
            if(i) printf(" ");
            printf("%I64d",dist[i]);
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-11-10 11:02:24

hdu 5361 2015多校联合训练赛#6 最短路的相关文章

HDU 5358(2015多校联合训练赛1006) First One (区间合并+常数优化)

HDU 5358 题意: 求∑?i=1?n??∑?j=i?n??(?log?2??S(i,j)?+1)?(i+j). 思路: S(i,j) < 10^10 < 2^34,所以log2(S)+1的值只可能在1~35之间.由于log变化缓慢的函数特性,我们可以S(i,n)分作多个相同log值的区间来计算,用pos[i][j]预处理记录每个以i为起点,log(s)值为j的区间的右边界,即可优化至nlogn的复杂度. 主要是写起来比较难一些,一些细节比较纠结,一定思路理清后再写. ps.此题卡常数毫无

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)

HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分相同,第一部分与第二部分对称. 现在给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法,求出以第i个点为中心的回文串长度,记录到数组p中 要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样. 因为我们已经记录下来以

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&amp;#39;s problem(manacher+二分/枚举)

pid=5371">HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分同样,第一部分与第二部分对称. 如今给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法.求出以第i个点为中心的回文串长度.记录到数组p中 要满足题目所要求的内容.须要使得两个相邻的回文串,共享中间的一部分,也就是说.左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也

hdu 5358 First One 2015多校联合训练赛#6 枚举

First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 142    Accepted Submission(s): 37 Problem Description soda has an integer array a1,a2,-,an. Let S(i,j) be the sum of ai,ai+1,-,aj. No

hdu 5381 The sum of gcd 2015多校联合训练赛#8莫队算法

The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 23    Accepted Submission(s): 4 Problem Description You have an array ,the length of  is Let Input There are multiple test cases.

hdu 5288||2015多校联合第一场1001题

http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a array A of size n ,defined a function f(l,r) represent the number of i (l<=i<=r) , that there's no j(l<=j<=r,j<>i) satisfy ai mod aj=0,now OO want to know ∑i

HDU OJ 5326 Work( 2015多校联合训练第3场) 并查集

题目连接:戳ME #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int M = 1e2+5; int n, k; int par[M]; int sum[M]; void find(int x) { if( par[x]!=x ) { sum[par[x]]++; find(par[x]); } else return; } int main() {

HDU OJ 5317 RGCDQ( 2015多校联合训练第3场) 暴力+小技巧

题目连接:戳ME 题意:在一个[L,R]内找到最大的gcd(f[i],f[j])其中L<=i<j<=R,f[x]表示i分解质因数后因子的种类数.eg:f[10]=2(10=2*5),f[12]=2(12=2*2*3). 分析:很容易想到先将f[x]求出来,这里x最大1e6,要在常数时间内求出f[x].并且稍加分析就知道1<=f[x]<=7,可以用一个dp[i][j]表示从f[1]到f[i]有多少个j.这样就可以在常数时间内预处理出来,后面在O(1)的时间内就可以输出结果.并且

2015多校联合训练第一场Tricks Device(hdu5294)

题意:给一个无向图,给起点s,终点t,求最少拆掉几条边使得s到不了t,最多拆几条边使得s能到t 思路: 先跑一边最短路,记录最短路中最短的边数,总边数-最短边数就是第二个答案 第一个答案就是在最短路里面求最小割,也就是求最大流,然后根据最短路在建个新图,权为1,跑一边网络流 模板题,以后就用这套模板了 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #incl