题目描述

在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国。两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉泽。 幻想历 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。你只需摧毁位于杰森国首都 的曾·布拉泽大神殿,杰森国的信仰,军队还有一切就都会土崩瓦解,灰飞烟灭。 为了尽量减小己方的消耗,你决定使用自爆机器人完成这一任务。唯一的困 难是,杰森国的一部分城市有结界保护,不破坏掉结界就无法进入城市。而每个 城市的结界都是由分布在其他城市中的一些结界发生器维持的,如果想进入某个 城市,你就必须破坏掉维持这个城市结界的所有结界发生器。 现在你有无限多的自爆机器人,一旦进入了某个城市,自爆机器人可以瞬间 引爆,破坏一个目标(结界发生器,或是杰森国大神殿),当然机器人本身也会 一起被破坏。你需要知道:摧毁杰森国所需的最短时间。
输入格式

第一行两个正整数 N, M。 接下来 M行,每行三个正整数 uiui​,vivi,wiwi,表示有一条从城市ui​到城市vi的单向道路,自爆机器人通过这条道路需要wiwi的时间。 之后 N 行,每行描述一个城市。首先是一个正整数 li,维持这个城市结界所 使用的结界发生器数目。之后lili个1~N 之间的城市编号,表示每个结界发生器的 位置。如果lili​=0,则说明该城市没有结界保护,保证l1l1=0 。

输出格式

仅包含一个正整数 ,击败杰森国所需的最短时间。

样例
输入样例

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

输出样例

5

数据范围与提示

对于 20%的数据,满足N≤15,M≤50;
对于 50%的数据,满足N≤500,M≤6,000;
对于 100%的数据,满足N≤3,000,M≤70,000,1≤wi​≤10^8
输入数据保证一定有解,且不会存在维持某个城市结界的结界发生器在这个城市内部。连接两个城市的道路可能不止一条, 也可能存在一个城市自己到自己的道路。

这道题是一道dijkstra的题目,只不过要做略微变形。用t1代表到达城市的最短时间,t2代表摧毁保护城市的所有结界发生器的最短时间,摧毁城市的最短时间即 MAX(t1,t2) 。

每次用 dis[x] 更新 t1[x可以到的点],再更新保护 x可以到的点的结界发生器数量即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
//快读
int read(){
int ret=;
char ch=getchar();
while(ch<'' || ch>''){
ch=getchar();
}while(ch>='' && ch<=''){
ret=(ret<<)+(ret<<)+ch-'';
ch=getchar();
}return ret;
}
struct dat{
int p,d;
};
vector <dat> v[];
vector <int> h[];
int t1[],t2[],dis[],cnt[];
//t1[i]代表到达城市i的最短时间 t2[i]代表摧毁保护城市i的所有结界发生器的最短时间 dis[i]代表摧毁城市i的最短时间
bool vis[];
priority_queue <pair<int,int> > q;//优先队列
//迪杰斯特拉
void dj(){
t1[]=;
dis[]=;
q.push(make_pair(,));
while(!q.empty()){
int x=q.top().second;
q.pop();
if(vis[x]){
continue;
}vis[x]=;
for(int i=; i<v[x].size(); i++){
if(!vis[v[x][i].p]){
int y=v[x][i].p;
int z=v[x][i].d;
if(t1[y]>dis[x]+z){
t1[y]=dis[x]+z;
if(!cnt[y]){
dis[y]=max(t1[y],t2[y]);
q.push(make_pair(-dis[y],y));
//优先队列默认大根堆,所以要取反
}
}
}
}for(int i=; i<h[x].size(); i++){
int y=h[x][i];
if(cnt[y]){
cnt[y]--;
t2[y]=max(dis[x],t2[y]);
if(!cnt[y]){
dis[y]=max(t1[y],t2[y]);
q.push(make_pair(-dis[y],y));
}
}
}
}
}
int main(){
//freopen("t4.in","r",stdin);
//freopen("d.out","w",stdout);
int n,m,x,y,z,tmp=;
dat u;
n=read();
m=read();
for(int i=; i<=m; i++){
x=read();
y=read();
z=read();
u.d=z;
u.p=y;
v[x].push_back(u);
}for(int i=; i<=n; i++){
x=read();
cnt[i]=x;
for(int j=; j<=x; j++){
y=read();
h[y].push_back(i);
}
}memset(t1,inf,sizeof(t1));
memset(dis,inf,sizeof(dis));
dj();
printf("%d",dis[n]);
return ;
}

SDOI2010_大陆争霸(邻接表存图)的更多相关文章

  1. QDUOJ 生化危机 邻接表存图+BFS

    生化危机 发布时间: 2015年10月10日 18:05   时间限制: 1000ms   内存限制: 256M 描述 X博士想造福人类, 研发一种可以再生肢体的药物, 可是很不幸......研究失败 ...

  2. 三种邻接表存图模板:vector邻接表、数组邻接表、链式前向星

    vector邻接表: ; struct Edge{ int u,v,w; Edge(int _u=0,int _v=0,int _w=0){u=_u,v=_v,w=_w;} }; vector< ...

  3. PTA 邻接表存储图的广度优先遍历(20 分)

    6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(V ...

  4. hdu 2647 (拓扑排序 邻接表建图的模板) Reward

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2647 老板给员工发工资,每个人的基本工资都是888,然后还有奖金,然后员工之间有矛盾,有的员工希望比某员 ...

  5. PTA 邻接表存储图的广度优先遍历

    试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ) 其中LGraph是邻接表存储的 ...

  6. c++邻接表存储图(无向),并用广度优先和深度优先遍历(实验)

    一开始我是用c写的,后面才发现广搜要用到队列,所以我就直接使用c++的STL队列来写, 因为不想再写多一个队列了.这次实验写了两个多钟,因为要边写边思考,太菜了哈哈. 主要参考<大话数据结构&g ...

  7. 数据结构(11) -- 邻接表存储图的DFS和BFS

    /////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...

  8. 邻接表存储图,DFS遍历图的java代码实现

    import java.util.*; public class Main{ static int MAX_VERTEXNUM = 100; static int [] visited = new i ...

  9. 数据结构C++使用邻接表实现图

    定义邻接表存储的图类.[实验要求] (1)创建一个邻接表存储的图:(2)返回图中指定边的权值:(3)插入操作:向图中插入一个顶点,插入一条边:(4)删除操作:从图中删除一个顶点,删除一条边:(5)图的 ...

随机推荐

  1. 简单python脚本,将jupter notebook的ipynb文件转为pdf(包含中文)

    直接执行的python代码ipynb2pdf.py 主要思路.将ipynb文件转成tex文件,然后使用latex编译成pdf.由于latex默认转换不显示中文,需要向tex文件中添加相关中文包. 依赖 ...

  2. python 查看安装的库的路径(找site-packages)

    import sysprint(sys.path) orwhich pythonwhich python3

  3. jenkins之docker安装(jenkins/jenkins:lts)

    建议使用此镜像安装,不要使用官网推荐的jenkinsci/blueocean镜像,使用它构建node程序会出现问题. 1.宿主服务器jenkins_home目录权限 为了方便安装插件,升级,迁移,因此 ...

  4. PHP 之去除代码中的注释

    测试文件代码如下: <?php /** * Created by PhpStorm. * User: Yang * Date: 2019/10/16 * Time: 10:25 */ // 计算 ...

  5. CF463E Caisa and Tree

    要是你们能和我一样看错题目意思误认为是要求互质的就舒服了. 考虑修改很少,所以修改完之后可以暴力遍历树. 那么现在问题转换成了如何求一个点的答案,直接把所有质因子存下来然后用\(set\)维护即可. ...

  6. scp执行报错WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

    linux环境执行scp时会遇到报错WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!,如下 [root@subsname home]# scp AAA. ...

  7. Python实现协程

    什么是进程和线程 有一定基础的小伙伴们肯定都知道进程和线程. 进程是什么呢? 直白地讲,进程就是应用程序的启动实例.比如我们运行一个游戏,打开一个软件,就是开启了一个进程. 进程拥有代码和打开的文件资 ...

  8. git submodule 如何push代码

    某git项目关联了一个submodule 如何更新该项目下的submodule https://stackoverflow.com/questions/5814319/git-submodule-pu ...

  9. java定时案例

    好久没写笔记了,变懒了! java定时运行的三个案例: 一, 通过sleep方法来达到定时任务的效果 public class testTime { public static void main(S ...

  10. js的一些兼容性易错的的问题

    一.属性相关 我们通常把特征(attribute)和属性(property)统称为属性,但是他们确实是不同的概念,特征(attribute)会表现在HTML文本中,对特征的修改一定会表现在元素的out ...