HDU 1568 Legal path (DP)
来源:互联网 发布:苹果mac笔记本 编辑:程序博客网 时间:2024/05/26 22:54
题目: LINK
题意:给定一个有向图,求1->n的“最短路”。这儿的“最短路”有限定条件----就是最短路上的每一条边的权值比上一条边(如果有的话)至少大k。
点数n 1e5, 边数m 2e5比较大。可以考虑DP的解法。
可以先把所有的边按照权值大小排序,最容易想到的是O(m^2)的解法。这样中间会遍历许多没有用的边,所以我们要优化一下。
我们可以发现,通过直接的边i, j到达x点, 如果权值val[i] > val[j], 那么一定要有到x点的最短路dis[i] < dis[j] (如果不是这样的话,就没有必要通过边i转移)
因此,对于每个点我们要按照连向他的边维护一个序列dp[i][...],递增递减关系如上。
如果利用边x (u -> v) 进行转移的时候,只需要在u的状态dp[u]里面边权小于x.val - k中边权最大的那一个(他的最短路一定是里面最小的),这个过程可以利用二分,如果他的最短路+x.val比v点其他边权值小的边转移出来的最短路都要小的话就留下来。
详见代码.
/* *********************************************** Author :Napoleon Created Time :2015-01-31 18:29:48 Problem :bc 28 c dp************************************************ */#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <string>#include <vector>#include <cmath>#include <queue>#include <map>#include <set>using namespace std; #define INF 1000000000typedef __int64 LL; #define N 233333int t, n, m, k; struct node {int u, v, w; }edge[N]; vector<pair<int, LL> > dp[N]; int cmp(node x, node y) {return x.w < y.w; }int gao(int id, int ma) {int l = 0, r = dp[id].size() - 1, m; int ret = -1; while(l <= r) {m = (l + r) >> 1; if(dp[id][m].first <= ma) {l = m + 1; ret = m; }else r = m - 1; }return ret; }int main() {#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin); #endif // ONLINE_JUDGEscanf("%d", &t); while(t--) {scanf("%d%d%d", &n, &m, &k); for(int i = 1;i <= m; i++) {scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w); }sort(edge+1, edge+1+m, cmp); for(int i = 0; i <= n; i++) dp[i].clear(); int last = 0 ;dp[1].push_back(make_pair(-1, 0)); for(int i = 1; i <= m; i++) {// printf("%d %d : %d \n", edge[i].u, edge[i].v, edge[i].w); while(last + 1 <= m && edge[last + 1].w + k <= edge[i].w) last ++; int u = edge[i].u, v = edge[i].v, w = edge[i].w; int x = gao(u, last); if(x == -1) continue; int vsize = dp[v].size(); if(vsize == 0 || dp[v][vsize - 1].second > dp[u][x].second + w) {dp[v].push_back(make_pair(i, dp[u][x].second + w)); }}int size = dp[n].size(); if(size == 0) puts("-1"); else printf("%I64d\n", dp[n][size - 1].second); }return 0; }
0 0
- HDU 1568 Legal path (DP)
- hdu 5168 Legal path
- hdu 5168 Legal path(DP,栈优化)
- HDU 5168 Legal path 最短路 OR DP
- hdu5168 Legal path DP,最短路
- Legal or Not HDU
- hdu Legal or Not
- Legal or Not HDU
- hdu 5492 Find a path (DP)
- [dp] hdu 5492 Find a path
- hdu 5492 Find a path DP
- hdu 5492 Find a path【dp】
- hdu 5492 Find a path(dp)
- HDU 5492 Find a path(DP)
- HDU 5492 Find a path(DP)
- HDU 2224The shortest path(dp)
- HDU 5492 Find a path【DP】
- Hdu 5492 Find a path【Dp】
- ImageLoader显示文件夹下的图片
- 再逢“最大公约数”
- 1005. 继续(3n+1)猜想 (25)
- [每天一个知识点]24-编程技巧-如何简单计算分页等需要进1的除法
- 【知识梳理向】Objective-C中的@property
- HDU 1568 Legal path (DP)
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭
- 给int赋最小值问题
- 防火墙知识点小结
- 数论里面的定理
- 【动态调试so文件】 + AliCrackMe_2分析记录
- 驯服腾讯的QQ(在此我谴责一下国内的软件制造商)
- android 日记
- USACO5.3.2 Window Area(window)