大陆争霸[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的堆优化,今天搞了一下...就是先弄一个优先队列,存每个点的数据,然后这个题就加了一点不一样的东西,每次的最短路算两次,一次是自己的最短路,另一次是机关的最短路,两者取最大值才是该点 ...
随机推荐
- SpringMVC——MVC
一.了解MVC mvc这种设计模式,分为三个基本部分:模型(Model).视图(View)和控制器(Controller),不光运用于Web领域,而且也能用于非Web领域:可以特指一种表现层设计模式, ...
- C# 反射的详细理解
网友A的解释: C# 反射机制的学习心得 首先说说,为什么要学习 反射 呢?有什么用啊. 在我们写程序的时候,经常会用到一些类中的方法,那么就要调用这些个类.如果不是在一个命名空间里时,就要引用相 ...
- git简介 http://msysgit.github.io/
集中式vs分布式 Linus一直痛恨的CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统,集中式和分布式版本控制系统有什么区别呢? 先说集中式版本控制系统,版本库是集中存放在中央服务 ...
- kuangbin专题 专题一 简单搜索 Prime Path POJ - 3126
题目链接:https://vjudge.net/problem/POJ-3126 题意:给你两个四位的素数N,M,每次改变N四位数中的其中一位,如果能经过有限次数的替换变成四位数M,那么求出最少替换次 ...
- free()函数释放一段分配的内存之陷阱
朋友们对malloc函数应该是比较熟悉了,此函数功能是分配一段内存地址,并且将内存地址给一个指针变量,最后记得再调用free函数释放这段内存地址就可以了,标准的流程对吧,好像没什么问题.但是按照此标准 ...
- python函数知识一 函数初始、定义与调用、返回值、参数和函数的好处+菜中菜
第四章 函数 1.函数初识: def :关键字 -- 定义 函数名:和变量的定义方式一样 (): 用于参数传递,: 形参:函数的定义中()内的是形参 实参:调用的()内是实参 传参:调用时将实参传递给 ...
- Excel催化剂开源第49波-Excel与PowerBIDeskTop互通互联之第三篇
在PowerBIDeskTop开启的SSAS服务,和Sqlserver所开启的一个本质的区别是,前者其端口号是随机生成的,即上一次打开获得的端口号,下一次关闭后再打开,系统分配给它新的端口号,而后者因 ...
- android在style中使用自定义属性 error: style attribute not found.
异常: Error:(128, 5) error: style attribute 'com.honghui0531.prebiotics.view:attr/item_right_icon_src' ...
- C语言入门6-选择结构--f语句-switch
一. 什么是选择结构? 选择结构,也称为分支结构!! 选择结构就是根据 给定的判定条件,判断结果, 并根据 判断的结果 来控制程序的流程 (流程图中, 菱形框 是有来判断的 , ...
- [leetcode] 542. 01 Matrix (Medium)
给予一个矩阵,矩阵有1有0,计算每一个1到0需要走几步,只能走上下左右. 解法一: 利用dp,从左上角遍历一遍,再从右下角遍历一遍,dp存储当前位置到0的最短距离. 十分粗心的搞错了col和row,改 ...