In Touch HDU- 5361(最短路+并查集)

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 
#include 
#include 
#include 
#include
#include 
#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 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<return 0;
}

你可能感兴趣的:(最短路,并查集)