P2446 [SDOI2010]大陆争霸

题目背景

在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的克里斯国。两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉泽。

幻想历8012年1月,杰森国正式宣布曾·布拉泽是他们唯一信仰的神,同时开始迫害在杰森国的信仰斯普林·布拉泽的克里斯国教徒。

幻想历8012年3月2日,位于杰森国东部小镇神谕镇的克里斯国教徒发动起义。

幻想历8012年3月7日,神谕镇的起义被杰森国大军以残酷手段镇压。

幻想历8012年3月8日,克里斯国对杰森国宣战。由数十万大军组成的克里斯军团开至两国边境,与杰森军团对峙。

幻想历8012年4月,克里斯军团攻破杰森军团防线进入神谕镇,该镇幸存的克里斯国教徒得到解放。

战争随后进入胶着状态,旷日持久。战况惨烈,一时间枪林弹雨,硝烟弥漫,民不聊生。

题目描述

幻想历8012年5月12日深夜,斯普林·布拉泽降下神谕:“Trust me, earn eternal life.”克里斯军团士气大增。作为克里斯军团的主帅,你决定利用这一机会发动奇袭,一举击败杰森国。具体地说,杰森国有\(N\)个城市,由\(M\)条单向道路连接。神谕镇是城市1而杰森国的首都是城市\(N\)。你只需摧毁位于杰森国首都的曾·布拉泽大神殿,杰森国的信仰,军队还有一切就都会土崩瓦解,灰飞烟灭。

为了尽量减小己方的消耗,你决定使用自爆机器人完成这一任务。唯一的困难是,杰森国的一部分城市有结界保护,不破坏掉结界就无法进入城市。而每个城市的结界都是由分布在其他城市中的一些结界发生器维持的,如果想进入某个城市,你就必须破坏掉维持这个城市结界的所有结界发生器。

现在你有无限多的自爆机器人,一旦进入了某个城市,自爆机器人可以瞬间引爆,破坏一个目标(结界发生器,或是杰森国大神殿),当然机器人本身也会一起被破坏。你需要知道:摧毁杰森国所需的最短时间。

输入输出格式

输入格式:

输入文件的landcraft.in的第一行两个正整数\(N\),\(M\)。

接下来\(M\)行,每行三个正整数\(u_i\), \(v_i\),\(w_i\),表示有一条从城市ui到城市vi的单向道路,自爆机器人通过这条道路需要\(w_i\)的时间。

之后\(N\)行,每行描述一个城市。首先是一个正整数\(l_i\),维持这个城市结界所使用的结界发生器数目。之后\(l_i\)个\(1\)~\(N\)之间的城市编号,表示每个结界发生器的位置。如果\(l_i=0\),则说明该城市没有结界保护,保证\(l_1=0\) 。

输出格式:

输出文件landcraft.out仅包含一个正整数 ,击败杰森国所需的最短时间。

说明

对于20%的数据,满足N≤15,M≤50;

对于50%的数据,满足N≤500,M≤6,000;

对于100%的数据,满足N≤3,000,M≤70,000,1≤wi≤108。

输入数据保证一定有解,且不会存在维持某个城市结界的结界发生器在这个城市内部。

连接两个城市的道路可能不止一条,也可能存在一个城市自己到自己的道路。


由于时间是并行的,而且机器人是无限的,所以抽象一下问题。

如果没有保护罩,其实就是普通的最短路。

加上了保护罩,就相当于给某些点设置了一些前置点。

我们可以缩点然后以拓扑排序为第一关键字,以前置点为第二关键字的顺序进行DP,然而这样比较麻烦。

考虑到最短路中dijkstra的每个点也只会使用一次,且这个出现顺序与拓扑排序的不冲突。

如果我们用dijkstra求,其实只需要考虑前置点的情况了。

事实上判起来可能会有点小细节,大家自己想吧

不知道SPFA有没有正确性。。


Code:

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#define ll long long
using namespace std;
const int N=3010;
const int M=70010;
int head[N],to[M],Next[M],cnt;
ll edge[M];
void add(int u,int v,ll w)
{
to[++cnt]=v;edge[cnt]=w;Next[cnt]=head[u];head[u]=cnt;
}
int n,m,in[N];
vector <int > prot[N];
void init()
{
scanf("%d%d",&n,&m);
int u,v;ll w;
for(int i=1;i<=m;i++)
{
scanf("%d%d%lld",&u,&v,&w);
add(u,v,w);
}
for(int p,cnt0,i=1;i<=n;i++)
{
scanf("%d",&cnt0);
in[i]=cnt0;
while(cnt0--)
{
scanf("%d",&p);
prot[p].push_back(i);
}
}
}
priority_queue <pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > q;
ll dis[N],disu[N];
int used[N],is[N];
void disj()
{
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(used[u]) continue;
used[u]=1;
for(int i=0;i<prot[u].size();i++)
{
int v=prot[u][i];
disu[v]=max(disu[v],dis[u]);
in[v]--;
if(!in[v]&&is[v])
{
dis[v]=max(dis[v],disu[v]);
q.push(make_pair(dis[v],v));
}
}
for(int i=head[u];i;i=Next[i])
{
int v=to[i],w=edge[i];
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
is[v]=1;
dis[v]=max(dis[v],disu[v]);//假装自己被松弛Orz
if(!in[v]) q.push(make_pair(dis[v],v));
}
}
}
}
int main()
{
init();
disj();
printf("%lld\n",dis[n]);
return 0;
}

2018.8.2

洛谷 P2446 [SDOI2010]大陆争霸 解题报告的更多相关文章

  1. 洛谷——P2446 [SDOI2010]大陆争霸

    https://www.luogu.org/problem/show?pid=2446#sub 题目背景 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的克里斯国.两个国家的人民分别 ...

  2. 洛谷 P2469 [SDOI2010]星际竞速 解题报告

    题目描述 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的梦想,来自杰森座α星的悠悠也是其中之一. 赛车大赛的赛场由N颗行星和M条双向星际航路构成,其 ...

  3. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  4. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  5. 洛谷 P3802 小魔女帕琪 解题报告

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  6. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  7. 洛谷1303 A*B Problem 解题报告

    洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...

  8. 洛谷 P2051 [AHOI2009]中国象棋 解题报告

    P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...

  9. 洛谷 P3084 [USACO13OPEN]照片Photo 解题报告

    [USACO13OPEN]照片Photo 题目描述 农夫约翰决定给站在一条线上的\(N(1 \le N \le 200,000)\)头奶牛制作一张全家福照片,\(N\)头奶牛编号\(1\)到\(N\) ...

随机推荐

  1. OSG-获取OSG的源代码和第三方库并编译

    获取OSG的源代码有很多方式. 这里说下其中的两个地方,第一就是中国的OSG网站http://www.osgchina.org/,这个网站目前应该是由中国西安恒歌科技维护,同时,西安恒歌科技也是一家已 ...

  2. OpenSUSE 11 安装Qt5.0,失败,失败,失败,留个坑,以后来填,万一实现了呢

    我又来无耻的写问题来了,这次还真的是没有解决,线留坑吧,万一以后实现了. 同样,这次也是以恶搞网友说听说想在open suse 上面安装5.0版本以后的Qt,自己折腾好几没有成功. 我一想,哎,这不是 ...

  3. Python拼接字符串的7种方法

    1.直接通过+操作: s = 'Python'+','+'你好'+'!'print(s) 打印结果: Python,你好! 2.通过join()方法拼接: 将列表转换成字符串 strlist=['Py ...

  4. 即刻开始使用Kotlin开发Android的12个原因(KAD 30)

    作者:Antonio Leiva 时间:Jul, 11, 2017 原文链接:https://antonioleiva.com/reasons-kotlin-android/ 这组文章已到最后了,它们 ...

  5. LabVIEW初篇---前言

    最早接触labview,是研二的时候,2007年,当时为了补贴家用,改善生活.自己拿着本科毕业证去找工作,去一个企业面试,当时,面试的主考官,问了会什么吗,比如PLC.单片机啥的?那时候的自己,基本上 ...

  6. Pyhton网络爬虫实例_豆瓣电影排行榜_Xpath方法爬取

    -----------------------------------------------------------学无止境------------------------------------- ...

  7. 【20180807模拟测试】tree

    题目描述 或许会传送失败的传送门 #分析 考虑如何才能让白边显得更(不)重要,即在每条白边上(加上)减去一个值. 我们可以二分这个值,然后用寻常方法做最小生成树.统计在此最小生成树里有多少白 边. 然 ...

  8. HADOOP docker(六):hive简易使用指南

    前言1.hive简介1.1 hive组件与相应功能:1.2 hive的表类型1.3 分区表1.3 分隔符1.4 hive的数据存储2.数据类型2.1 基本数据类型2.1 复杂数据类型2.3 NULL3 ...

  9. Python中的namespace package

    在Python 3.3之前,一个目录想被当成package被导入,必须包含__init__.py文件:而在Python 3.3及以后的版本中,__init__.py文件可以不需要,直接使用import ...

  10. Bad Cowtractors(最大生成树)

      Description Bessie has been hired to build a cheap internet network among Farmer John's N (2 <= ...