zoukankan      html  css  js  c++  java
  • luoguP2939 [USACO09FEB]改造路Revamping Trails

    约翰一共有N)个牧场.由M条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场1出发到牧场N去给奶牛检查身体.

    通过每条小径都需要消耗一定的时间.约翰打算升级其中K条小径,使之成为高 速公路.在高速公路上的通行几乎是瞬间完成的,所以高速公路的通行时间为0.

    请帮助约翰决定对哪些小径进行升级,使他每天早上到牧场W花的时间最少.输出这个最少 的时间.

    分层图DP,启发良多

    1、远离SPFA,Dijstra+堆稳定多了

    2、要在Dijstra中Dp,堆中必须包含三要素:当前点、层数、距离,缺一不可

    3、若当前点更新过,可以continue

    4、大根堆中排序标准要倒着写
    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define re register
    #define il inline
    #define ll long long
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=100050;
    int n,m,h[N],cnt,k,dp[N][30];
    bool vis[N][30];
    struct Edge
    {
      int to,next,w;
    }e[N<<2];
    struct node
    {
      int u,t,dis;
      bool operator < (const node &x) const
      {return dis>x.dis;}
    };
    priority_queue<node>Q;
    il void add(re int u,re int v,re int w)
    {
      e[++cnt]=(Edge){v,h[u],w};h[u]=cnt;
    }
    il int gi()
    {
      re int x=0,t=1;
      re char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    il void SPFA()
    {
      memset(dp,63,sizeof(dp));
      dp[1][0]=0;Q.push((node){1,0,0});
      while(!Q.empty())
        {
          re int u=Q.top().u,j=Q.top().t;Q.pop();
          if(vis[u][j]) continue;vis[u][j]=1;
          for(re int i=h[u];i;i=e[i].next)
        {
          re int v=e[i].to;
          if(j+1<=k)
            if(dp[v][j+1]>dp[u][j])
              {
                dp[v][j+1]=dp[u][j];
                Q.push((node){v,j+1,dp[v][j+1]});
              }
              if(dp[v][j]>dp[u][j]+e[i].w)
            {
              dp[v][j]=dp[u][j]+e[i].w;
          Q.push((node){v,j,dp[v][j]});
            }
        }
        }
    }
    int main()
    {
      n=gi();m=gi();k=gi();
      fp(i,1,m)
        {
          re int u=gi(),v=gi(),w=gi();
          add(u,v,w);add(v,u,w);
        }
      SPFA();
      printf("%d ",dp[n][k]);
      return 0;
    }
     

  • 相关阅读:
    linux自动挂载
    VUE 封装 api类
    数据库中如何判断某参数为空就不执行where条件
    axios 拦截 , 页面跳转, token 验证(非本人原创)
    springboot 集成 WebSocket (非本人原创)
    spring cloud整合 websocket 的那些事
    前后端消息推送
    spring cloud 之eureka配置
    spring cloud 之demo
    linux 进程的 5 大段
  • 原文地址:https://www.cnblogs.com/yanshannan/p/8459320.html
Copyright © 2011-2022 走看看