• In Touch(dijk+并查集优化)


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

    The 11-st soda is their leader and he wants to know the minimum cost needed to reach ii-th soda (1≤i≤n)(1≤i≤n). 

    Input

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

    The first line contains an integer nn (1≤n≤2×105)(1≤n≤2×105), the number of soda. 
    The second line contains nn integers l1,l2,…,lnl1,l2,…,ln. The third line contains nn integers r1,r2,…,rnr1,r2,…,rn. The fourth line contains nn integers c1,c2,…,cnc1,c2,…,cn. (0≤li≤ri≤n,1≤ci≤109)(0≤li≤ri≤n,1≤ci≤109)

    Output

    For each case, output nn integers where ii-th integer denotes the minimum cost needed to reach ii-th soda. If 11-st soda cannot reach ii-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++.

    其实每个点只更新一次就可以

    但是由于我们每次更新都要遍历一个范围

    因此我们就不能每次都暴力的跑出更新的值

    所以我们就想到使用并查集的方法进行优化

    用并查集跑数组的好处就是可跳过没必要的点

    从而降低时间复杂度

    #define LOCAL
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    using namespace std;
    int l[200005],r[200005];
    long long c[200005];
    int father[200005];
    int n;
    long long dis[200005];
    void intal()
    {
        for(int i=0;i<=n+5;i++) father[i]=i;
    }
    struct node
    {
        int id;
        long long num;
        node (int p,long long q): id(p),num(q){}
        friend bool operator < (node p,node q)
        {
            return p.num>q.num;
        }
    };
    int fin(int x)
    {
        if(x==father[x]) return x;
        return father[x]=fin(father[x]);
    }
    void dijk()
    {
        memset(dis,0x3f,sizeof(dis));
        priority_queue<node>q;
        dis[1]=0;
        father[1]=2;
        q.push(node(1,c[1]));
        while(q.size())
        {
            //cout<<q.size()<<endl;
            int tmp1=q.top().id;
            long long tmp2=q.top().num;
            q.pop();
            for(int i=1;i>=-1;i-=2)
            {
                int lf,rt;
                lf=tmp1+i*l[tmp1];
                rt=tmp1+i*r[tmp1];
                lf=max(0,lf),lf=min(n+1,lf);
                rt=max(0,rt),rt=min(n+1,rt);
                if(lf>rt) swap(lf,rt);
                for(int j=lf;j<=rt;j++)
                {
                   //cout<<"lf"<<lf<<"rt"<<rt<<j<<" "<<fin(j)<<father[2]<<endl;
                    j=fin(j);
                    if(j>rt||j<0||j>n) break;
                    dis[j]=tmp2;
                    father[j]=fin(j+1);
                    q.push(node(j,tmp2+c[j]));
                }
                //cout<<"wdnmd"<<endl;
            }
        }
    }
    int main()
    {
        #ifdef LOCAL
        freopen("in.txt","r",stdin);
        #endif
        int t;  
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            intal();
            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("%lld",&c[i]);
            dijk();
            for(int i=1;i<=n;i++)
            {
                if(dis[i]>1e18) printf("-1%c",i==n?'
    ':' ');
                else printf("%lld%c",dis[i],i==n?'
    ':' ');
            }
        }
    }
  • 相关阅读:
    ruby计算平方和开方
    Silverlight中DataGrid翻页或者滚动时CheckBox/RadioButton显示的问题
    bat文件设置ip地址
    gcc编译多线程
    TCP Nagle算法
    fork父子进程 信号处理
    Unix守护进程的创建示例
    inline内联函数
    volatile类型
    ioctl获取接口名称、IP地址、MAC地址、广播地址等
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852239.html
Copyright © 2020-2023  润新知