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

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

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

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#define LL __int64
using namespace std;
const LL INF=(LL)0x3f3f3f3f*0x3f3f3f3f;
const int N=;
const int M=; struct TEdge{
int u,v,w;
bool operator<(const TEdge& a)const {
if(w<a.w) return true;
return false;
}
}Cedge[M];
int tot;
struct Point{
int lw;
LL alw;
Point(int c,LL e){lw=c; alw=e;}
}; vector<Point>point[N];
int n,m,k; void addedge(int u,int v,int w){
Cedge[tot].u=u;
Cedge[tot].v=v;
Cedge[tot].w=w;
tot++;
} void Push_into(int p,Point t){
point[p].push_back(t);
} bool cmp(Point a,Point b){
if(a.lw==b.lw) return a.alw>b.alw;
return a.lw<b.lw;
} int main(){
int T,u,v,w,sz;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);
tot=;
for(int i=;i<=n;i++){
point[i].clear();
}
for(int i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
sort(Cedge,Cedge+tot);
for(int i=;i<tot;i++){
u=Cedge[i].u;
v=Cedge[i].v;
if(u==){
if(point[v].empty()){
Push_into(v,Point(Cedge[i].w,Cedge[i].w));
}
else{
if(point[v][point[v].size()-].alw>Cedge[i].w){
Push_into(v,Point(Cedge[i].w,Cedge[i].w));
}
}
continue;
}
if(point[u].empty()) continue;
else {
int p=upper_bound(point[u].begin(),point[u].end(),Point(Cedge[i].w-k,-INF),cmp)-point[u].begin();
if(p==) continue;
else if(p> && p<point[u].size()) --p;
else if(point[u][point[u].size()-].lw<=Cedge[i].w-k) p=point[u].size()-;
else continue;
if(point[v].empty())
Push_into(v,Point(Cedge[i].w,point[u][p].alw+(LL)Cedge[i].w));
else if(point[v][point[v].size()-].alw>point[u][p].alw+(LL)Cedge[i].w)
Push_into(v,Point(Cedge[i].w,point[u][p].alw+(LL)Cedge[i].w));
}
}
if(point[n].empty())
printf("-1\n");
else printf("%I64d\n",point[n][point[n].size()-].alw);
}
return ;
}

HDU 5168的更多相关文章

  1. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  3. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  4. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  5. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  6. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  7. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

  8. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

  9. hdu 4329

    problem:http://acm.hdu.edu.cn/showproblem.php?pid=4329 题意:模拟  a.     p(r)=   R'/i   rel(r)=(1||0)  R ...

随机推荐

  1. POJ3570 Fund Management 动态规划

    题目大意 Frank从个人投资者获得了c美元的资金,可用于m天的投资.Frank可以对n(n<=8)支股票进行投资.对于每一支股票:都有一个交易上限si,表示一天最多能交易的股数:还有一个上限k ...

  2. 高效管理 Elasticsearch 中基于时间的索引——本质是在利用滚动模式做数据的冷热分离,热索引可以用ssd

    高效管理 Elasticsearch 中基于时间的索引 转自:http://stormluke.me/es-managing-time-based-indices-efficiently/ 用 Ela ...

  3. hdoj--1150--Machine Schedule(最小点覆盖)

    Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  4. hdoj--2767--Proving Equivalences (scc+缩点)

    Proving Equivalences Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other ...

  5. 在Spring Boot中使用Spring-data-jpa实现分页查询

    转自:https://www.cnblogs.com/sandea/p/8275890.html 在我们平时的工作中,查询列表在我们的系统中基本随处可见,那么我们如何使用jpa进行多条件查询以及查询列 ...

  6. 使用python进行re拆分网页内容

    这里简短的总结一下而不是完全的罗列python的re模块,python的re具有强大的功能,如下是一个从我们学校抓取数据然后拆分的程序,代码如下: import httplib import urll ...

  7. AHOI 2009 (BZOJ1798)维护序列 seq (线段树好题?)

    我是不会说这个题很坑的.. 改了一晚上... // by SiriusRen #include <cstdio> #define N 150000 #define LSON l,mid,l ...

  8. html中<frameset>标签,框架结构各窗口的父级菜单子级菜单关系

    这个问题搞得我头大,并且在查过百度后各位大佬给出的解释我都不能理解,应该是我太白的原因,希望我写的能好理解. 下面文章窗口1.2.3,在代码里分别为chuangkou.chuangkou1.chuan ...

  9. 【SQL】SELECT 语句

    1.1 SELECT基本语法: Select * |{[distinct]colum|expression [alias],…} from table; 1.2 查询当前用户所有在用的表及视图: HR ...

  10. 写给VC++ Windows开发的初学者 一片不错的博文

    不知不觉2010年都过了半年了,想来我学C语言已经12个年头了(从1998年开始),用VC++也有11年了,最早使用Turbo C2.0 ,也学过汇编,后来使用Borland C++3.0 .Micr ...