acdrem1083 人民城管爱人民 DP
思路:d(i, 0)表示从节点i到达大运村的最短路径,d(i, 1)表示从节点i到达大运村的次短路径。
1.最短路:当做DAG处理即可。
2.次短路:假设当前在u点处,下一个节点是v。v到终点的最短路是d(v, 0),次短路是d(v, 1),u到v的距离是w(u, v),只能封锁一条路,即只能删除一条边。分成两种情况:
a.将封锁用在了v点到达终点的路上,则此时GG拥有主动权,可以选择最小的路径,即Imin = min(w(u, v) + d(v, 1)),;
b.将封锁用在u-v这条路径上面,则此时城管拥有主动权,可以封锁最短路径,则GG这能选择次短路径Hmin。
则d(u, 1) = max(Imin, Hmin)
AC代码
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 10000 + 5;
int n, m;
int d[maxn][2], in[maxn], Top[maxn], c[maxn*20];
struct Edge{
int from, to, dist, nex;
Edge() {}
Edge(int u, int v, int d, int ne):from(u), to(v), dist(d), nex(ne){}
}edge[maxn*20];
int edgenum, head[maxn];
void add_edge(int u, int v, int dis) {
edge[edgenum] = Edge(u, v, dis, head[u]);
head[u] = edgenum++;
}
void topsort() { //逆向拓扑序
queue<int>q;
for(int i = 0; i < n; ++i) if(!in[i]) q.push(i);
int num = 0;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u]; i != -1; i = edge[i].nex) if(i&1){
int v = edge[i].to;
--in[v];
if(!in[v]) q.push(v);
}
Top[num++] = u;
}
}
void solve(int u) {
if(u == n-1) {d[u][0] = d[u][1] = 0; return;} //终点
int num = 0, Imin = inf;
for(int i = head[u]; i != -1; i = edge[i].nex) if(!(i&1)){
int v = edge[i].to;
//最短路
d[u][0] = min(d[u][0], d[v][0] + edge[i].dist);
//次短路
Imin = min(Imin, d[v][1] + edge[i].dist); // GG掌握主动权
c[num++] = d[v][0] + edge[i].dist; //城管有主动权
}
if(num < 2) {d[u][1] = inf; return;} //GG无法到达从u到达终点
int fir = c[0], sec = c[1]; //最小和次小
if(fir > sec) swap(fir, sec);
for(int i = 2; i < num; ++i) {
if(c[i] <= fir) {
sec = fir;
fir = c[i];
}
else sec = min(sec, c[i]);
}
d[u][1] = max(Imin, sec);
if(d[u][1] > inf) d[u][1] = inf;
if(d[u][0] > inf) d[u][0] = inf;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
edgenum = 0;
memset(head, -1, sizeof(head));
memset(d, inf, sizeof(d));
memset(in, 0, sizeof(in));
scanf("%d%d", &n, &m);
int u, v, dis;
for(int i = 0; i < m; ++i) {
scanf("%d%d%d", &u, &v, &dis);
add_edge(u, v, dis);
add_edge(v, u, dis);
in[u]++;
}
topsort();
for(int i = 0; i < n; ++i) {
solve(Top[i]);
}
if(d[0][1] >= inf) printf("-1\n");
else printf("%d\n", d[0][1]);
}
return 0;
}
如有不当之处欢迎指出!
acdrem1083 人民城管爱人民 DP的更多相关文章
- ACdream 1083 人民城管爱人民
拓扑排序,然后从终点开始递推. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio ...
- ACdream 1083 有向无环图dp
题目链接:点击打开链接 人民城管爱人民 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Othe ...
- 机房人民大团结(DP)
最近,机房出了一个不团结分子:Dr.Weissman.他经常欺骗同学们吃一种“教授糖豆”,使同学们神志不清,殴打他人,砸烂计算机,破坏机房团结.幸运地,一个和谐家认清了Dr.Weissman的本质.机 ...
- 【BZOJ-1040】骑士 树形DP + 环套树 + DFS
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3312 Solved: 1269[Submit][Status ...
- 优化DP的奇淫技巧
DP是搞OI不可不学的算法.一些丧心病狂的出题人不满足于裸的DP,一定要加上优化才能A掉. 故下面记录一些优化DP的奇淫技巧. OJ 1326 裸的状态方程很好推. f[i]=max(f[j]+sum ...
- 【BZOJ】1040: [ZJOI2008]骑士(环套树dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1040 简直不能再神的题orz. 蒟蒻即使蒟蒻,完全不会. 一开始看到数据n<=1000000就 ...
- bzoj 1040: [ZJOI2008]骑士 環套樹DP
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1755 Solved: 690[Submit][Status] ...
- bzoj 1040: [ZJOI2008]骑士 树形dp
题目链接 1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3054 Solved: 1162[Submit][S ...
- 【环套树+树形dp】Bzoj1040 [ZJOI2008] 骑士
Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火 ...
随机推荐
- js swipeDelete 滑动删除
先上图看看整体实际效果 看看用法 与参数 默认参数 var defaults = { distance:80, //滑动距离 units:'px', //默认单位 touchStart:functio ...
- 华人开创NTP网络授时服务器成功投运世界级超大工程港珠澳大桥
华人开创NTP网络授时服务器成功投运世界级超大工程港珠澳大桥 本文由北京华人开创公司提供请勿转载 2017年12月中旬,我华人开创生产研发的NTP网络授时服务器成功投运世界级超大工程港珠澳大桥,为这个 ...
- fscanf和fprintf
fscanf和fprintf fscanf的字符串是在键盘的缓冲区,fprintf是在显示器的缓冲区. 1.函数原型: int fprintf(FILE *fp, const char *format ...
- 32位系统装4G以上的内存
1.操作系统在32位平台上最大寻址空间是4GB,如果要使用4GB以上的内存,就必须使用intel的PAE(物理地址扩展)模式,在windows NT平台实现PAE只需对boot.ini加上/pae即可 ...
- PHP支付第3方接口使用方法。
去年写过一遍博客文章. 网站申请不到支付宝接口.微信接口,免接口收款实现方式. 网络在发展,支付宝也好,微信也好,技术在进步,这种方式已经不能使用了,明显的一个问题是,支付宝的刷新工具,会定时退出,必 ...
- 初码-Azure系列-存储队列的使用与一个Azure小工具(蓝天助手)
初码Azure系列文章目录 将消息队列技术模型简化,并打造成更适合互联网+与敏捷开发的云服务模式,好像已经是行业趋势,阿里云也在推荐使用消息服务(HTTP协议为主)而来替代消息队列(TCP协议.MQT ...
- Java源码分析系列之HttpServletRequest源码分析
从源码当中 我们可以 得知,HttpServletRequest其实 实际上 并 不是一个类,它只是一个标准,一个 接口而已,它的 父类是ServletRequest. 认证方式 public int ...
- C# Ioc ASP.NET MVC Dependency Injection
ASP.NET MVC Dependency Injection 同志们,非常快速的Ioc注册接口和注入Mvc Controller,步骤如下: 安装Unity.Mvc NuGet Package 在 ...
- 2017年总结的前端文章——CSS高级技巧汇总
1. 页面顶部阴影 body:before{ content: ""; position: fixed; top:-10px; left:; width: 100%; height ...
- Java对正则表达式的支持(二)
正则表达式的主要用途: a.在目标字符串中找出匹配正则表达式的部分 b.校验目标字符串是否符合正则表达式,例如校验邮箱地址 c.在目标字符串中替换符合正则表达式的部分为其他的字符串 Scanner类是 ...