zoukankan      html  css  js  c++  java
  • HDU 5168

    把边按权值排序后,就相当于求一个子序列以1开始和以n结束。由于边权递增,而且相差>=k,所以,边的顺序也必定是递增的。知道,当处理一条出边时,必定是从入边选择一条最优的边,考虑两个因素,入边的权值和入边以前的总的代价。优化很容易想到,每个结点维护一个数组,就不需要从头扫描边数组了。但这个维护的结点的数组在两个因素符合什么条件呢。。。卡住了。。

    参考了题解之后,是按入边来维护,当入边权值增大而总代价下降。这样,二分查找出总代价最小而且符合边约束的。要知道,入边权值增大是自然符合的,因为边数组在开始时就已经由小到大排列。所以,当处理到目的顶点v,到达V的总代价比结点数组的最高点还小,则把该边加入到结点数组中即可。

    其中,二分使用upper_bound查找上界,学习了http://blog.csdn.net/whai362/article/details/43385107,谢谢了。。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cmath>
     5 #include <cstring>
     6 #include <vector>
     7 #define LL __int64
     8 using namespace std;
     9 const LL INF=(LL)0x3f3f3f3f*0x3f3f3f3f;
    10 const int N=100010;
    11 const int M=200020;
    12 
    13 struct TEdge{
    14     int u,v,w;
    15     bool operator<(const TEdge& a)const {
    16         if(w<a.w) return true;
    17         return false;
    18     }
    19 }Cedge[M];
    20 int tot;
    21 struct Point{
    22     int lw;
    23     LL alw;
    24     Point(int c,LL e){lw=c; alw=e;}
    25 };
    26 
    27 vector<Point>point[N];
    28 int n,m,k;
    29 
    30 void addedge(int u,int v,int w){
    31     Cedge[tot].u=u;
    32     Cedge[tot].v=v;
    33     Cedge[tot].w=w;
    34     tot++;
    35 }
    36 
    37 void Push_into(int p,Point t){
    38     point[p].push_back(t);
    39 }
    40 
    41 bool cmp(Point a,Point b){
    42     if(a.lw==b.lw) return a.alw>b.alw;
    43     return a.lw<b.lw;
    44 }
    45 
    46 int main(){
    47     int T,u,v,w,sz;
    48     scanf("%d",&T);
    49     while(T--){
    50         scanf("%d%d%d",&n,&m,&k);
    51         tot=0;
    52         for(int i=1;i<=n;i++){
    53             point[i].clear();
    54         }
    55         for(int i=1;i<=m;i++){
    56             scanf("%d%d%d",&u,&v,&w);
    57             addedge(u,v,w);
    58         }
    59         sort(Cedge,Cedge+tot);
    60         for(int i=0;i<tot;i++){
    61             u=Cedge[i].u;
    62             v=Cedge[i].v;
    63             if(u==1){
    64                 if(point[v].empty()){
    65                     Push_into(v,Point(Cedge[i].w,Cedge[i].w));
    66                 }
    67                 else{
    68                     if(point[v][point[v].size()-1].alw>Cedge[i].w){
    69                         Push_into(v,Point(Cedge[i].w,Cedge[i].w));
    70                     }
    71                 }
    72                 continue;
    73             }
    74             if(point[u].empty()) continue;
    75             else {
    76                 int p=upper_bound(point[u].begin(),point[u].end(),Point(Cedge[i].w-k,-INF),cmp)-point[u].begin();
    77                 if(p==0) continue;
    78                 else if(p>0 && p<point[u].size()) --p;
    79                 else if(point[u][point[u].size()-1].lw<=Cedge[i].w-k) p=point[u].size()-1;
    80                 else continue;
    81                 if(point[v].empty())
    82                     Push_into(v,Point(Cedge[i].w,point[u][p].alw+(LL)Cedge[i].w));
    83                 else if(point[v][point[v].size()-1].alw>point[u][p].alw+(LL)Cedge[i].w)
    84                     Push_into(v,Point(Cedge[i].w,point[u][p].alw+(LL)Cedge[i].w));
    85             }
    86         }
    87         if(point[n].empty())
    88         printf("-1
    ");
    89         else printf("%I64d
    ",point[n][point[n].size()-1].alw);
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    【topcoder SRM 702 DIV 2 250】TestTaking
    【24.67%】【codeforces 551C】 GukiZ hates Boxes
    【TP SRM 703 div2 500】 GCDGraph
    【TP SRM 703 div2 250】AlternatingString
    【35.02%】【codeforces 734A】Vladik and flights
    Android总结篇系列:Android Service
    java之常用正则表达式
    一种软件定义的固态盘融合存储方法
    MongoDB常用语句
    编程界十大顶级IDE
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4288282.html
Copyright © 2011-2022 走看看