• [USACO08JAN]电话线Telephone Lines(分层图)/洛谷P1948


    这道题其实是分层图,但和裸的分层图不太一样。因为它只要求路径总权值为路径上最大一条路径的权值,但仔细考虑,这同时也满足一个贪心的性质,那就是当你每次用路径总权值小的方案来更新,那么可以保证新的路径权值尽量小。

    所以这道题在不删边的情况下可以使用Dij来跑,而删边权的情况就是分层图。

    所以就拿分层图来搞好了^_^。

    由于这个数据p和k都比较大,所以直接建k+1层图是要爆的,而k+1层图边都一样,我们就用dis[层数(0-k)]来表示。

    具体的就是每次Dij转移是要分两种情况:

    1.在原层跑,也就是说,在这层中用Dij
    2.若下一层边的另一端不够优秀,就用这一层来直接更新,当然就是把这一端的点的解直接复制

    大概就是这样了

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct tmp{
     7   int no;
     8   int ler;
     9   int dis;
    10   bool friend operator < (tmp x,tmp y)
    11   {
    12     return x.dis>y.dis;
    13   }
    14 };
    15 struct pnt{
    16   int no;
    17   int hd;
    18   int dis[1005];
    19   bool vis[1005];
    20 }p[1005];
    21 struct ent{
    22   int twd;
    23   int lst;
    24   int vls;
    25 }e[50000];
    26 int n,m,d;
    27 int cnt;
    28 priority_queue<tmp>Q;
    29 void ade(int f,int t,int v)
    30 {
    31   cnt++;
    32   e[cnt].twd=t;
    33   e[cnt].lst=p[f].hd;
    34     p[f].hd=cnt;
    35     e[cnt].vls=v;
    36 }
    37 int main()
    38 {
    39     scanf("%d%d%d",&n,&m,&d);
    40     for(int i=1;i<=n;i++)
    41     {
    42         p[i].no=i;
    43         for(int j=0;j<=d;j++)
    44         {
    45             p[i].dis[j]=0x3f3f3f3f;
    46         }
    47     }
    48     p[1].dis[0]=0;
    49     for(int i=1;i<=m;i++)
    50     {
    51         int a,b,c;
    52         scanf("%d%d%d",&a,&b,&c);
    53         ade(a,b,c);
    54         ade(b,a,c);
    55     }
    56     tmp x;
    57     x.no=1;
    58     x.ler=0;
    59     x.dis=0;
    60     Q.push(x);
    61     while(!Q.empty())
    62     {
    63         x=Q.top();
    64         Q.pop();
    65         int nw=x.no;
    66         int t=x.ler;
    67         if(x.no==n&&x.ler==d)
    68         {
    69             printf("%d
    ",x.dis);
    70             return 0;
    71         }
    72         if(p[nw].vis[t])continue;
    73         p[nw].vis[t]=true;
    74         for(int i=p[nw].hd;i;i=e[i].lst)
    75         {
    76             int to=e[i].twd;
    77             if(p[to].dis[t]>max(p[nw].dis[t],e[i].vls))
    78             {
    79                 p[to].dis[t]=max(p[nw].dis[t],e[i].vls);
    80                 x=(tmp){to,t,p[to].dis[t]};
    81                 Q.push(x);
    82             }
    83             if(p[to].dis[t+1]>p[nw].dis[t]&&t<d)
    84             {
    85                 p[to].dis[t+1]=p[nw].dis[t];
    86                 x=(tmp){to,t+1,p[to].dis[t+1]};
    87                 Q.push(x);
    88             }
    89         }
    90     }
    91     printf("-1
    ");
    92     return 0;
    93 }
    94 
    95 telephone line

    其实,这道题还可以二分来搞,我就不赘述了主要是我太懒了

  • 相关阅读:
    react中refs的使用
    在npm发布自己造的轮子
    如何阅读一本书——分析阅读模板
    如何阅读一本书——检视阅读模板
    Redis教程——检视阅读
    如何阅读一本书——分析阅读Pre
    SVN常用功能介绍(二)
    SVN常用功能介绍(一)
    分页sql大全
    .NetCore 登录(密码盐+随机数)
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9376335.html
Copyright © 2020-2023  润新知