There are n soda living in a straight line. soda are numbered by 1,2,…,n from left to right. The distance between two adjacent soda is 1 meter. Every soda has a teleporter. The teleporter of i-th soda can teleport to the soda whose distance between i-th soda is no less than li and no larger than ri. The cost to use i-th soda’s teleporter is ci.
The 1-st soda is their leader and he wants to know the minimum cost needed to reach i-th soda (1≤i≤n).
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤2×105), the number of soda.
The second line contains n integers l1,l2,…,ln. The third line contains n integers r1,r2,…,rn. The fourth line contains n integers c1,c2,…,cn. (0≤li≤ri≤n,1≤ci≤109)
Output
For each case, output n integers where i-th integer denotes the minimum cost needed to reach i-th soda. If 1-st soda cannot reach i-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++.
思路这题在做的的时候,是看出来是最短路了,但是在极端情况下,边的个数会达到n方,交了一发果然超时了,一直在想怎么优化,没想到啊 …用并查集的思想了。差一点。
代码
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include<iostream>
#include <cstring>
#define maxx 200005
using namespace std;
typedef long long LL;
const LL INF = 1LL<<62;
int l[maxx],r[maxx];
int w[maxx];
int pre[maxx];
int findd(int x)
{
return pre[x]==x?x:pre[x]=findd(pre[x]);
}
int n;
long long dis[maxx];
struct node
{
long long val;
int index;
node(long long x, int y)
{
val=x;
index=y;
}
bool operator<(const node& b) const {
return val > b.val;
}
};
void init(int x)
{
for(int i=1;i<=x;i++)
pre[i]=i,dis[i]=INF;
}
void spfa()
{
init(n+3);
priority_queue<node> que;
dis[1]=w[1];
que.push(node(dis[1],1));
while(que.size())
{
node temp=que.top();que.pop();
int u=temp.index;
for(int i=-1;i<=1;i+=2)
{
int L=u+i*l[u];
int R=u+i*r[u];
if(L>R)swap(L,R);
L=max(L,1);
R=min(R,n);
if(L>R)
continue;
int now=L;
for(;;)
{
now=findd(now);
if(now<=0||now>R)
break;
if(dis[now]>dis[u]+w[now])
{
dis[now]=dis[u]+w[now];
que.push(node(dis[now],now));
}
pre[findd(now)]=findd(now+1);
}
}
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
init(n+1);
for(int i=1;i<=n;i++)
scanf("%d",l+i);
for(int i=1;i<=n;i++)
scanf("%d",r+i);
for(int i=1;i<=n;i++)
scanf("%d",w+i);
spfa();
cout<<0;
for(int i=2;i<=n;i++)
printf(" %lld",dis[i]==INF?-1:dis[i]-w[i]);
cout<<endl;
}
return 0;
}

本文介绍了一个关于寻找最短路径的问题,通过并查集进行优化解决。问题涉及一系列节点,每个节点都有对应的传送范围及成本。文章提供了一种有效的方法来计算从起始节点到达其他各节点所需的最小成本。
928

被折叠的 条评论
为什么被折叠?



