大陆争霸[SDOI2010]带限制最短路
只要你有无限个自爆机器人,你就能为所欲为 斯普林·布拉泽
【题目描述】
略
一句话题意:
杰森国有 \(N\) 个城市,由 \(M\) 条单向道 路连接。杰森国的首都是城市 \(N\)。你只需摧毁杰森国首都就能获胜。为了尽量减小己方的消耗,你决定使用自爆机器人完成这一任务。唯一的困难是,杰森国的一部分城市有结界保护,不破坏掉结界就无法进入城市。而每个城市的结界都是由分布在其他城市中的一些结界发生器维持的,如果想进入某个城市,你就必须破坏掉维持这个城市结界的所有结界发生器。 现在你有无限多的自爆机器人,一旦进入了某个城市,自爆机器人可以瞬间引爆,破坏一个目标(结界发生器,或是杰森国首都),当然机器人本身也会一起被破坏。你需要知道:击败杰森国所需的最短时间。
【输入格式】
第一行两个正整数 N, M。 接下来 M行,每行三个正整数 \(u_i, v_i ,w_i\),表示有一条从城市\(u_i\)到城市\(v_i\)的单向道路,自爆机器人通过这条道路需要\(w_i\)的时间。之后 \(N\) 行,每行描述一个城市。首先是一个正整数 \(l_i\),代表维持这个城市结界所使用的结界发生器数目。之后\(l_i\)个\(1\)~\(N\) 之间的城市编号,表示每个结界发生器的 位置。如果\(l_i = 0\),则说明该城市没有结界保护,保证\(l_1 = 0\)。
【输出格式】
仅包含一个正整数 ,击败杰森国所需的最短时间。
【思路点拨】
如果没有结界的限制,很明显此题就只需要跑一遍\(Dijkstra\)就过了。
第一眼看到这题就想到拓扑排序。
当时在考场上先写了一个最短路算每个点到源点的最短距离,然后根据结界发生器的拓扑序更新\(ans[i] = max(dist[i], ans[j])\),其中城市\(j\)的结界发生器维持城市\(i\)结界。
大样例一次过,美滋滋
考试结束,

\(\color{red}{Wrong\ Answer\qquad10}\)
不过,其实这题也就只需要在最短路算法上小小的改动一下就行了。
开三个数组\(dist, tme, ans\),\(dist[i]\)表示源点到点\(i\)的最短距离,\(tme[i]\)表示点\(i\)最早在此时解除结界,\(ans[i]\)则表示城市\(i\)最早能在\(ans[i]\)时被炸飞。
显然,\(ans[i] = max(dist[i], tme[i])\)。
而对于\(tme[i]\),\(\forall j \in L[i], tme[i] = max(ans[j])\),其中\(L[i]\)代表维持城市\(i\)结界的城市的集合。
然后直接跑一遍\(Dijkstra\), 不过要在更新完\(L[i]\)中所有的城市后才能将\(i\)入堆。
最后的答案就是\(ans[n]\),时间复杂度\(O(m log n)\)。
【代码实现】
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define re register
using namespace std;
typedef long long ll;
ll n, m;
ll head[100005], pre[150005], to[150005], val[150005], len;
ll h2[100005], p2[100005], t2[100005], l2, in[100005], ans[100005], dis[100005], tme[100005];
bool vis[100005];
ll read() {
ll ret = 0, flag = 1;
char ch = getchar();
while (ch > '9' || ch < '0') {
if (ch == '-') flag = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
ret = ret * 10 + ch - '0';
ch = getchar();
}
return ret * flag;
}
void insert(ll u, ll v, ll w) {
to[++len] = v, val[len] = w, pre[len] = head[u], head[u] = len;
}
void insert2(ll u, ll v) {
t2[++l2] = v, p2[l2] = h2[u], h2[u] = l2;
}
void dijkstra() {
for (re int i = 1; i <= n; i++) dis[i] = 0x7fffffff;
dis[1] = tme[1] = ans[1] = 0;
priority_queue< pair<ll, ll> , vector< pair<ll, ll> > , greater< pair<ll, ll> > > q;
q.push(make_pair(0, 1));
while (!q.empty()) {
ll c = q.top().second;
q.pop();
if (vis[c]) continue;
vis[c] = 1;
for (re ll i = head[c]; i != 0; i = pre[i]) {
if (ans[c] + val[i] < dis[to[i]]) {
dis[to[i]] = ans[c] + val[i];
if (!in[to[i]]) {
ans[to[i]] = max(dis[to[i]], tme[to[i]]);
q.push(make_pair(ans[to[i]], to[i]));
}
}
}
for (re ll i = h2[c]; i != 0; i = p2[i]) {
if (in[t2[i]]) {
in[t2[i]]--;
tme[t2[i]] = max(tme[t2[i]], ans[c]);
if (!in[t2[i]]) {
ans[t2[i]] = max(dis[t2[i]], tme[t2[i]]);
q.push(make_pair(ans[t2[i]], t2[i]));
}
}
}
}
}
int main() {
n = read();
m = read();
ll u, v, w;
for (re int i = 1; i <= m; i++) {
u = read(), v = read(), w = read();
insert(u, v, w);
}
for (re int i = 1; i <= n; i++) {
in[i] = read();
for (re int j = 1; j <= in[i]; j++) {
u = read();
insert2(u, i);
}
}
dijkstra();
printf("%lld\n", ans[n]);
return 0;
}
大陆争霸[SDOI2010]带限制最短路的更多相关文章
- GDOI#348大陆争霸[SDOI2010]最短路有限制条件
在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉 ...
- BZOJ-1922 大陆争霸 多限制、分层图最短路 (堆+dijkstra)
1922: [Sdoi2010]大陆争霸 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1154 Solved: 478 [Submit][Status ...
- 洛谷 P2446 [SDOI2010]大陆争霸 解题报告
P2446 [SDOI2010]大陆争霸 题目背景 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭的神曾·布拉 ...
- bzoj1922 [SDOI2010]大陆争霸 分层图
问题描述 幻想历8012年5月12日深夜,斯普林·布拉泽降下神谕:“Trust me, earn eternal life.”克里斯军团士气大增.作为克里斯军团的主帅,你决定利用这一机会发动奇袭,一举 ...
- 【BZOJ1922】大陆争霸(最短路)
[BZOJ1922]大陆争霸(最短路) 题面 BZOJ 洛谷 题解 最短路变形题. 定义\(dis\)表示最短路,\(d\)表示最早可以进入当前点的时间.显然\(d=max(max(dis_v,d_v ...
- AC日记——[SDOI2010]大陆争霸 洛谷 P3690
[SDOI2010]大陆争霸 思路: dijkstra模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn ...
- BZOJ1922:[SDOI2010]大陆争霸(最短路)
Description 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光 ...
- BZOJ1922 [Sdoi2010]大陆争霸 【最短路】
题目 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林 ...
- B1922 [Sdoi2010]大陆争霸 最短路
我一直都不会dij的堆优化,今天搞了一下...就是先弄一个优先队列,存每个点的数据,然后这个题就加了一点不一样的东西,每次的最短路算两次,一次是自己的最短路,另一次是机关的最短路,两者取最大值才是该点 ...
随机推荐
- Python与C/C++相互调用
参考链接:https://www.cnblogs.com/yanzi-meng/p/8066944.html
- java高并发系列-第1天:必须知道的几个概念
java高并发系列-第1天:必须知道的几个概念 同步(Synchronous)和异步(Asynchronous) 同步和异步通常来形容一次方法调用,同步方法调用一旦开始,调用者必须等到方法调用返回后, ...
- CMinpack使用介绍
github: https://github.com/devernay/cminpack 主页: http://devernay.github.io/cminpack/ 使用手册: http://de ...
- 【译】.NET Core 3.0 发布自包含单体可执行程序
.NET Core 提供的发布应用程序选项 self-contained 是共享应用程序的好方法,因为应用程序的发布目录包含所有组件.运行时和框架.您只需要告诉使用者应用程序的入口 exe 文件,就可 ...
- 用Python玩数据-笔记整理-第二章
条件结构: if语句: if expression: #比较/成员/逻辑运算符 expr_true_suite #代码块必须缩进4个空格 else语句: if expression: expr_tru ...
- java-org.springframework.core.convert.ConversionFailedException- 前端传string解析date异常
关于SpringMVC前台日期作为实体类对象参数类型转换错误解决 异常信息: Field error in object 'tblHouse' on field 'houseTime': reject ...
- [leetcode] 7. Reverse Integer (easy)
原题 水题 唯一注意的点就是数字溢出 class Solution { public: int reverse(int x) { long long MAX = ((long long)1 <& ...
- ASP.NET登录验证码解决方案
目录 #验证码效果图 #代码 0.html代码 1.Handler中调用验证码生成类 2.验证码图片绘制生成类 3.高斯模糊算法类 #注意 #参考 在web项目中,为了防止登录被暴力破解,需要在登录的 ...
- Docker 工作原理及容器化简易指南
Docker 非常棒! 它使软件开发者无需担心配置和依赖性,在任何地方打包,发送和运行他们的应用程序.而在与 Kubernetes 相结合后,它使应用集群部署和管理变得更方便.这使得 Docker 深 ...
- 利用TCP协议,实现基于Socket的小聊天程序(初级版)
TCP TCP (Transmission Control Protocol)属于传输层协议.其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送.可靠性.有效流控.全双工操作和多路复用 ...