• HDU 4479 权递增的最短路问题


    题目大意:

    找一条节点 1 到节点 N 的最短路,保证这条路上每一条边都比前一条边长

    dp[i] 表示在当前状态下1到i的最小值

    先将所有边根据边的长度排一个序,再每次取出同一段相同长度的边去更新当前图中的每一个点可以更新的dp值,当然我们不能不能因为这相同的边长相互影响,所以不能边找边的同时边松弛dp值,因为可能 1-2:1  2-3:1,也就是说第一次其实不能由1到3这个点,但是你先更新1-2,那么2-3会因为2的dp值存在而可以松弛,所以,先找到所有可行的能进行迟缓的边记录在rec[]数组中,再把里面所有的边弛缓一遍

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 const int N = 10005;
     7 typedef long long LL;
     8 LL dp[N];
     9 int n , m , k;
    10 
    11 struct Path{
    12     int x,y,d;
    13     bool operator<(const Path &m)const{
    14         return d < m.d;
    15     }
    16 }p[100005];
    17 
    18 struct Rec{
    19     int x,y;
    20     LL d;
    21     Rec(int x=0,int y=0,LL d=0):x(x),y(y),d(d){}
    22 }rec[100005];
    23 
    24 void update(int l , int r)
    25 {
    26     int t = 0;
    27 
    28     for(int i=l;i<=r;i++){
    29         int u = p[i].x , v = p[i].y;
    30         if(dp[u] >= 0 && (dp[v] > dp[u] + p[i].d || dp[v] < 0))
    31         {
    32             rec[t++] = Rec(u,v, dp[u] + p[i].d);
    33         }
    34         if(dp[v] >= 0 && (dp[u] > dp[v] + p[i].d || dp[u] < 0))
    35         {
    36             rec[t++] = Rec(v,u, dp[v] + p[i].d);
    37         }
    38     }
    39 
    40     for(int i=0;i<t;i++){
    41         int u = rec[i].x , v = rec[i].y;
    42         if(dp[v] > rec[i].d || dp[v] < 0)
    43         {
    44             dp[v] = rec[i].d;
    45         }
    46     }
    47 }
    48 
    49 void add_edge(int x,int y,int d)
    50 {
    51     p[k].x = x , p[k].y = y , p[k++].d = d;
    52 }
    53 
    54 void solve()
    55 {
    56     sort(p,p+k);
    57     memset(dp,-1,sizeof(dp));
    58     dp[1] = 0;
    59     int l=0;
    60     for(int r=1 ; r<k;r++){
    61         if(p[r].d != p[r-1].d){
    62             update(l , r-1);
    63             l=r;
    64         }
    65     }
    66     update(l,k-1);
    67     if(dp[n] < 0)
    68         puts("No answer");
    69     else
    70         printf("%I64d
    ",dp[n]);
    71 }
    72 
    73 int main()
    74 {
    75    // freopen("test.in","rb",stdin);
    76 
    77     int T,a,b,d;
    78     scanf("%d",&T);
    79     while(T--){
    80         scanf("%d%d",&n,&m);
    81 
    82         k=0;
    83         memset(G , -1 , sizeof(G));
    84         for(int i=0;i<m;i++){
    85             scanf("%d%d%d",&a,&b,&d);
    86             add_edge(a,b,d);
    87         }
    88         solve();
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    cs61b project1
    CS61b lab5
    leetcode DP
    Leetcode 还未解决的bug
    Git使用总结
    Mac TensorFlow Anaconda
    eclipse C++ ld: 1 duplicate symbol for architecture x86_64
    Leetcode Hashtable 1-5
    EC 601 PYTHONPATH
    EC 601 OpenCV Install
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4041396.html
Copyright © 2020-2023  润新知