题目链接:点击打开链接

人民城管爱人民

Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Others)
SubmitStatistic Next Problem

Problem Description

一天GG正在和他的后宫之中的一个的MM在外面溜达。MM突然说了一句,“我想吃鸡蛋灌饼”……当他们吃的正high的时候。城管出现了。作为传说中的最强军事力量,卖鸡蛋灌饼的小贩在他们面前也仅仅算是战力为的5的渣滓,一秒钟就被秒杀了……

在这场屠杀中,GG和他的后宫本来仅仅是围观群众。可是不幸的是,城管看到了GG胃里的鸡蛋灌饼。他们要逮捕GG!可是GG显然不能让他们如愿,于是GG带着后宫開始了往大运村的逃亡之旅。

整个地图有n个路口,灌饼摊在0号路口。大运村在n-1号路口。有m条仅仅能单向通过的道路连接这n个路口,每条道路用一个正整数表示走过须要的时间。

整个地图没有环路,但两个路口之间可能有多条通路。如今GG希望以最短的时间到大运村,但不幸的是,城管为了抓住他动用了卫星对他进行空中跟踪,并且会在某一时刻空降到某一条道路上进行封锁(封锁会在瞬间完毕。可惜动静太大了GG也能在第一时间知道哪条道路被封锁了),之后这条路就无法通过了。在整个行动中仅仅会出现一次空降。并且不会在GG经过这条道路的时候进行封锁,也就是说。不会在GG在某条路上走了一半的时候封锁这条路。并且。城管们希望尽可能的延缓GG到达大运村的时间。

如今GG希望知道。自己多久能到达大运村。方便安排之后和其它后宫的约会。

注意两方是以博弈的思想来进行选择,即GG希望时间最短,城管希望时间最长,并且他们都很聪明会做出最佳的选择。

Input

输入第一行为数据组数T(T<=30)。

每组数据第一行包括两个整数n,m(2<=n<=10000,1<=m<=100000),表示路口数和道路数。之后m行描写叙述了全部的道路,每行有三个整数u,v,w(0<=u,v<n,0<w<=1000)。表示路口u到路口v有一条须要w时间走过的道路。

Output

对于每组数据输出一个整数。表示GG最后到达大运村须要的时间。假设GG无法到达大运村,输出-1。

Sample Input

2
5 6
0 1 1
1 2 1
2 4 1
1 4 3
0 3 2
3 4 1
3 4
0 1 1
0 1 2
1 2 3
1 2 4

Sample Output

4
5

Source

Dshawn

思路:

1、首先这个dp一定是逆向拓扑序(把全部边反向进行拓扑排序),这样我们在计算u点时。通过有向边(u->v)把u点的状态从v点转移过来,能保证v点一定是已计算过的

2、用dis[i]表示i点到终点的最短路,dp[i]表示i点到终点的删边最短路(这里所谓的删边,删除的边是在i-终点的路径上)

3、那么我们设GG站在u点。通过u->v的边把状态从v转移过来。

4、计算dis[u]比較easy,就是min(dis[v]+edge[i].dis)

5、计算dp[u]:依据定义dp[u] 是删边最短路。则删除的边是在u-终点的路径上,那么显然有2种情况

1)删除u-v这样的与u相连的边

2)删除v-终点上的边

对于2):那么GG有主动权。显然是选择edge[i].dis + dp[v] 中最小的(我们设这个最小值为smin)

对于1):军队拥有主动权,军队一定选择删掉一条边。那么删完以后GG自然还是选择走最短路。也就是GG仅仅能选择edge[i].dis+dis[v] 中次小值(设这个值为dmin

这里注意的是。军队拥有的主动权是能够随意选择一条边。所以dp[u]=max(dmin, smin)

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<set>
#include<queue>
#include<math.h>
#include<map>
using namespace std;
#define N 10050
#define M 100500
#define inf 10000000
struct Edge{int from, to, dis, nex;
}edge[M<<1];
int head[N], edgenum;
void add(int u, int v, int d){Edge E={u,v,d,head[u]};edge[edgenum] = E;head[u] = edgenum++;
}int n,m;
int sp[N], in[N];
void topsort(){//把图进行拓扑序queue<int>q;for(int i = 0; i < n; i++)if(in[i]==0)q.push(i);int top = 0;while(!q.empty()){int u = q.front(); q.pop();sp[top++] = u;for(int i = head[u]; ~i; i = edge[i].nex)if(i&1){int v = edge[i].to;in[v]--;if(!in[v])q.push(v);}}
}
int dp[N][2], a[M];//dp[u][0]表示1到u的最短路 dp[u][1]表示1到u的次小最短路
void work(int u){if(u == n-1){ dp[u][0] = dp[u][1] = 0; return ; }int top = 0, smin = inf;for(int i = head[u]; ~i; i = edge[i].nex)if(!(i&1)){int v = edge[i].to;dp[u][0] = min(dp[u][0], dp[v][0]+edge[i].dis);smin = min(smin, dp[v][1]+edge[i].dis);a[top++] = dp[v][0] + edge[i].dis;}if(top<2){dp[u][1] = inf; return ;}int fir = a[0], sec = a[1];if(fir>sec)swap(fir,sec);for(int i = 2; i < top; i++){if(a[i]<=fir)sec = fir, fir = a[i];else sec = min(sec, a[i]);}dp[u][1] = max(smin, sec);
}
void init(){memset(head, -1, sizeof head);edgenum = 0;}
int main(){int T, i, j, u, v, d;scanf("%d",&T);while(T--){init();memset(in, 0, sizeof in);scanf("%d %d",&n,&m);while(m--){scanf("%d %d %d",&u,&v,&d);add(u,v,d);add(v,u,d);in[u]++;}topsort();for(i = 0; i < n; i++)dp[i][0] = dp[i][1] = inf;for(i = 0; i < n; i++)work(sp[i]);if(dp[0][1]==inf)dp[0][1] = -1;printf("%d\n",dp[0][1]);}return 0;
}

ACdream 1083 有向无环图dp相关推荐

  1. bzoj 1179 抢掠计划atm (缩点+有向无环图DP)

    bzoj 1179 抢掠计划atm (缩点+有向无环图DP) 手动博客搬家: 本文发表于20170716 10:58:18, 原地址https://blog.csdn.net/suncongbo/ar ...

  2. 【学习笔记】有向无环图上的DP

    [学习笔记]有向无环图上的DP 手动博客搬家: 本文发表于20180716 10:49:04, 原地址https://blog.csdn.net/suncongbo/article/details/8 ...

  3. 2016 湖南省省赛B题《有向无环图》

    题目链接[https://vjudge.net/problem/CSU-1804] 题意: 给出一个有向无环图,然后让你算下面的结果,count(i,j)表示i->j之间的路径条数. 题解: 根 ...

  4. 有向无环图中的拓扑排序

    ´有向无环图(DAG),指不存在环的有向图 ´点的入度,指以这个点为结束点的边数 ´点的出度,指以这个点为出发点的边数 ´拓扑序就是对于节点的一个排列使得若(u,v)∈E,那么u在排列中出现的位置一定 ...

  5. 【图论】有向无环图的拓扑排序

    1. 引言 有向无环图(Directed Acyclic Graph, DAG)是有向图的一种,字面意思的理解就是图中没有环.常常被用来表示事件之间的驱动依赖关系,管理任务之间的调度.拓扑排序是对DA ...

  6. 算法精解:DAG有向无环图

    DAG是公认的下一代区块链的标志.本文从算法基础去研究分析DAG算法,以及它是如何运用到区块链中,解决了当前区块链的哪些问题. 关键字:DAG,有向无环图,算法,背包,深度优先搜索,栈,BlockCh ...

  7. C#实现有向无环图(DAG)拓扑排序

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在 ...

  8. 【网络流24题】D、魔术球问题(有向无环图的最小路径覆盖、思维)

    D.魔术球问题(有向无环图的最小路径覆盖.思维)[省选/NOI- ] P2765 魔术球问题 [问题分析] 枚举答案转化为判定性问题,然后最小路径覆盖,可以转化成二分图最大匹配,从而用最大流解决. [ ...

  9. 【网络流24题】解题报告:C、最小路径覆盖问题(有向无环图最小路径覆盖)(最大流)

    C.最小路径覆盖问题(有向无环图最小路径覆盖)(最大流)[省选/NOI- ] 拆点最大流 [问题分析] 有向无环图最小路径覆盖,可以转化成二分图最大匹配问题,从而用最大流解决. [建模方法] 构造二分 ...

最新文章

  1. 深度学习(2)基础2 -- 分类:得分函数损失函数(损失、正则化惩罚项、梯度下降、学习率)概率
  2. 10-CSS基础-CSS选择器
  3. 苹果系统怎么降低版本_1903、1809...到底怎么看系统版本?
  4. Factory模式与Prototype模式的异同
  5. Oracle入门(七)之表空间
  6. 修改DOS窗口编码格式
  7. clamav Java_ClamAV安装使用及API例子
  8. 一直在构建工作空间_智能工作空间让Dropbox拥有无限扩展潜力
  9. Codeforces Round #402 D String Game(二分)
  10. Ballast,一种精准控制 Go GC 提高性能的方法
  11. 单片机模拟计算机课设,单片机课程设计题目汇总(全)
  12. crossdomain.xml跨越
  13. 首次曝光!支付宝支付加密规则梳理,写的太好了!
  14. TamronOS IPTV系统任意用户添加修改
  15. 快速了解 Log4j的日志级别
  16. C++ Qt实现WPS、浏览器tab页面
  17. 西门子S7-1200PLC与FANUC机器人进行PROFINET IO通信的具体方法和步骤详解
  18. 活动回顾|Apache Doris 向量化技术实现与后续规划
  19. [洛谷1849] 拖拉机
  20. odoo中关于打印word格式的文件,利用docxtemplate方法

热门文章

  1. 转换营销阵地 特步的世界杯身影
  2. 2018.9.8-9.8 统计学课程笔记(2)-参数统计
  3. 转载:Java 内存区域和GC机制
  4. 流量不够用?Facebook要帮你发现附近的免费WiFi
  5. Struts 2的输入校验(二)
  6. 个人开发者帐号+wireless install 实现非app store程序的在线更新功能
  7. CSS漂亮盒子(上)
  8. Confluence 6 导入 SSL 证书和问题解决
  9. Linux系统 误删除kvm虚拟机数据恢复方法-数据恢复成功案例
  10. MyEclipse搭建java Web项目开发环境