zoukankan      html  css  js  c++  java
  • Hdu 5361 In Touch (dijkatrs+优先队列)

    题目链接:

      Hdu 5361  In Touch

    题目描述:

      有n个传送机排成一排,编号从1到n,每个传送机都可以把自己位置的东西传送到距离自己[l, r]距离的位置,并且花费c,问从1号传送机到其他传送机的最小花费是多少??

    解题思路:

      看了题解发现是dijkstra(求最短单源路径)+并查集(优化),刚开始的时候并不知道怎么用并查集优化,然后就提交了一个没有并查集的代码,果断TLE。然后开始搜代码,突然惊叹真是优化的太美妙。因为每次从队列中取出的都是最优的,所以更新dis的时候可以直接把这些点合并,下次再遇到这些点的时候没必要更新就直接跳过。(在这里要特别谢谢为我debug快要疯了的天I火聚聚)

     1 #include <cmath>
     2 #include <queue>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <iostream>
     6 #include <algorithm>
     7 using namespace std;
     8 typedef long long LL;
     9 const LL INF = 1LL<<62;
    10 const int maxn = 200005;
    11 struct node
    12 {
    13     int x;
    14     LL dis;
    15     node (int a, LL b):x(a),dis(b){}
    16     friend bool operator < (node a, node b)
    17     {
    18         return a.dis > b.dis;
    19     }
    20 };
    21 int l[maxn], r[maxn], c[maxn], father[maxn], n;
    22 LL dis[maxn];
    23 int Find (int x)
    24 {
    25     if (x != father[x])
    26         father[x] = Find (father[x]);
    27         return father[x];
    28 }
    29 void Merge (int x, int y)
    30 {
    31     int px = Find(x);
    32     int py = Find(y);
    33     if (px == py)
    34         return ;
    35     father[px] = py;
    36 }
    37 void dijkstra (int x)
    38 {
    39     priority_queue <node> Q;
    40     dis[x] = c[x];
    41     Q.push(node(x, dis[x]));
    42     while (!Q.empty())
    43     {
    44         int p = Q.top().x;
    45         Q.pop();
    46         for (int i=-1; i<=1; i+=2)
    47         {
    48             int L = p + l[p]*i;
    49             int R = p + r[p]*i;
    50             if (L > R)
    51                 swap(L, R);
    52             L = max (L, 1);
    53             R = min (R, n);
    54             for (int j=L; j<=R; j++)
    55             {
    56                 j = Find (j);
    57                 if ( j > R)
    58                     break;
    59                 if (dis[j] > dis[p] + c[j])
    60                 {
    61                     dis[j] = dis[p] + c[j];
    62                     Q.push(node(j, dis[j]));
    63                 }
    64                 Merge (j, j+1);
    65             }
    66         }
    67     }
    68 }
    69 int main ()
    70 {
    71     int t;
    72     scanf ("%d", &t);
    73     while (t --)
    74     {
    75         scanf ("%d", &n);
    76         for (int i=1; i<=n; i++)
    77             scanf ("%d", &l[i]);
    78         for (int i=1; i<=n; i++)
    79             scanf ("%d", &r[i]);
    80         for (int i=1; i<=n; i++)
    81             scanf ("%d", &c[i]);
    82         for (int i=0; i<=n+1; i++)
    83             {
    84                 father[i] = i;
    85                 dis[i] = INF;
    86             }
    87             dijkstra (1);
    88         for (int i=1; i<=n; i++)
    89         {
    90             if (dis[i] == INF)
    91                 dis[i] = c[i] - 1;
    92             printf ("%lld%c", dis[i]-c[i], i==n?'
    ':' ');
    93         }
    94     }
    95     return 0;
    96 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    SDUT 1299 最长上升子序列
    HDU 1754 I Hate It
    SDUT 2080 最长公共子序列问题
    HDU 1102 Constructing Roads HDU1863 畅通工程
    HDU 1166 敌兵布阵
    HDU 1874 畅通工程续
    准备翻译Windows 8 动手实验系列教程
    Windows 8 动手实验系列教程 简介
    一起学Windows phone7开发(十九. Windows phone7发布)
    一起学Windows phone7(十六. windows phone 7 developer tool RTM 发布)
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4714505.html
Copyright © 2011-2022 走看看