• 2015多校第6场 HDU 5361 并查集,最短路


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5361

    题意:有n个点1-n, 每个点到相邻点的距离是1,然后每个点可以通过花费c[i]的钱从i点走到距离i点大于等于l[i]并且小于等于r[i]的点,问从节点1到每个节点的最短距离是多少?不能到达的话,输出-1。

    题解参考:http://blog.csdn.net/jtjy568805874/article/details/47341905

    解法:这题的难点主要在于边的条数过多,不能像普通的最短路那样子跑。不过此题的特点在于对于每个点来说,从这个点出去能到的任何点这个过程的花费是相同的,都是cost[i]。于是假设到达该点的距离为dis[i]则从该点能到的任何点j的值都是dis[j]=min(dis[j],dis[i]+cost[i]);于是只要按照dis[i]+cost[i]排序,当前最先的第一个点能到的点的距离一定都是最近的,这些点在这之后都不会再被更新了。这样只要维护一个并查集压缩路径,或者维护一个set存可能还会被更新的点就好了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn = 2e5+10;
    struct FastIO
    {
        static const int S = 1310720;
        int wpos;
        char wbuf[S];
        FastIO() : wpos(0) {}
        inline int xchar()
        {
            static char buf[S];
            static int len = 0, pos = 0;
            if(pos == len)
                pos = 0, len = fread(buf, 1, S, stdin);
            if(pos == len)
                exit(0);
            return buf[pos ++];
        }
        inline unsigned long long xuint()
        {
            int c = xchar();
            unsigned long long x = 0;
            while(c <= 32)
                c = xchar();
            for(; '0' <= c && c <= '9'; c = xchar())
                x = x * 10 + c - '0';
            return x;
        }
        inline long long xint()
        {
            long long s = 1;
            int c = xchar(), x = 0;
            while(c <= 32)
                c = xchar();
            if(c == '-')
                s = -1, c = xchar();
            for(; '0' <= c && c <= '9'; c = xchar())
                x = x * 10 + c - '0';
            return x * s;
        }
        inline void xstring(char *s)
        {
            int c = xchar();
            while(c <= 32)
                c = xchar();
            for(; c > 32; c = xchar())
                * s++ = c;
            *s = 0;
        }
        inline double xdouble()
        {
            bool sign = 0;
            char ch = xchar();
            double x = 0;
            while(ch <= 32)
                ch = xchar();
            if(ch == '-')
                sign = 1, ch = xchar();
            for(; '0' <= ch && ch <= '9'; ch = xchar())
                x = x * 10 + ch - '0';
            if(ch == '.')
            {
                double tmp = 1;
                ch = xchar();
                for(; ch >= '0' && ch <= '9'; ch = xchar())
                    tmp /= 10.0, x += tmp * (ch - '0');
            }
            if(sign)
                x = -x;
            return x;
        }
        inline void wchar(int x)
        {
            if(wpos == S)
                fwrite(wbuf, 1, S, stdout), wpos = 0;
            wbuf[wpos ++] = x;
        }
        inline void wint(long long x)
        {
            if(x < 0)
                wchar('-'), x = -x;
            char s[24];
            int n = 0;
            while(x || !n)
                s[n ++] = '0' + x % 10, x /= 10;
            while(n--)
                wchar(s[n]);
        }
        inline void wstring(const char *s)
        {
            while(*s)
                wchar(*s++);
        }
        inline void wdouble(double x, int y = 6)
        {
            static long long mul[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000LL, 100000000000LL, 1000000000000LL, 10000000000000LL, 100000000000000LL, 1000000000000000LL, 10000000000000000LL, 100000000000000000LL};
            if(x < -1e-12)
                wchar('-'), x = -x;
            x *= mul[y];
            long long x1 = (long long) floorl(x);
            if(x - floor(x) >= 0.5)
                ++x1;
            long long x2 = x1 / mul[y], x3 = x1 - x2 * mul[y];
            wint(x2);
            if(y > 0)
            {
                wchar('.');
                for(size_t i = 1; i < y && x3 * mul[i] < mul[y]; wchar('0'), ++i);
                wint(x3);
            }
        }
        ~FastIO()
        {
            if(wpos)
                fwrite(wbuf, 1, wpos, stdout), wpos = 0;
        }
    } io;
    LL n, T, d[maxn], l[maxn], r[maxn], c[maxn], fa[maxn], ans, sum;
    struct cmp{
        bool operator ()(const LL &x, const LL &y) const{
            return d[x]+c[x]>d[y]+c[y];
        }
    };
    
    namespace DSU{
        int fa[maxn];
        void init(){
            for(int i=1; i<=n+1; i++) fa[i]=i;
        }
        int find_set(int x){
            if(x == fa[x]) return x;
            else return fa[x] = find_set(fa[x]);
        }
        void union_set(int x, int y){
            int fx = find_set(x), fy = find_set(y);
            if(fx != fy){
                fa[fx] = fy;
            }
        }
    }
    
    using namespace DSU;
    
    void Dijstra(int x)
    {
        priority_queue<LL,vector<LL>,cmp>q;
        d[x] = 0;
        q.push(x);
        while(q.size())
        {
            LL L,R,u = q.top(); q.pop();
            L = u-r[u], R = u-l[u];
            if(R>0){
                for(LL j=max(L,1LL); ; j++){
                    j = find_set(j);
                    if(j>min(R,n)) break;
                    if(d[j] > d[u]+c[u]){
                        d[j] = d[u]+c[u];
                        q.push(j);
                    }
                    union_set(j,j+1);
                }
            }
            L = u+l[u], R = u+r[u];
            if(L<=n){
                for(LL j=L;;j++){
                    j = find_set(j);
                    if(j>min(R,n)) break;
                    if(d[j]>d[u]+c[u]){
                        d[j] = d[u]+c[u];
                        q.push(j);
                    }
                    union_set(j,j+1);
                }
            }
        }
        return;
    }
    
    int main()
    {
        int T;
        T = io.xint();
        while(T--)
        {
            n = io.xint();
            sum = 0;
            for(int i=1; i<=n; i++) l[i] = io.xint();
            for(int i=1; i<=n; i++) r[i] = io.xint();
            for(int i=1; i<=n; i++) c[i] = io.xint(), sum+=c[i];
            init();
            for(int i=1; i<=n; i++) d[i] = sum+1;
            Dijstra(1);
            for(int i=1; i<=n; i++){
                if(d[i] == sum+1) d[i] = -1;
                if(i<n) printf("%lld ", d[i]);
                else printf("%lld
    ", d[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
    跟我学SpringCloud | 第十一篇:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪
    跟我学SpringCloud | 第十篇:服务网关Zuul高级篇
    跟我学SpringCloud | 第九篇:服务网关Zuul初
    跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线
    跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh
    跟我学SpringCloud | 第六篇:Spring Cloud Config Github配置中心
    跟我学SpringCloud | 第五篇:熔断监控Hystrix Dashboard和Turbine
    跟我学SpringCloud | 第四篇:熔断器Hystrix
    跟我学SpringCloud | 第三篇:服务的提供与Feign调用
  • 原文地址:https://www.cnblogs.com/spfa/p/7356688.html
Copyright © 2020-2023  润新知