1922: [Sdoi2010]大陆争霸
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1675 Solved: 729
[Submit][Status][Discuss]
Description
在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国。两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉泽。 幻想历 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。你只需摧毁位于杰森国首都 的曾·布拉泽大神殿,杰森国的信仰,军队还有一切就都会土崩瓦解,灰飞烟灭。 为了尽量减小己方的消耗,你决定使用自爆机器人完成这一任务。唯一的困 难是,杰森国的一部分城市有结界保护,不破坏掉结界就无法进入城市。而每个 城市的结界都是由分布在其他城市中的一些结界发生器维持的,如果想进入某个 城市,你就必须破坏掉维持这个城市结界的所有结界发生器。 现在你有无限多的自爆机器人,一旦进入了某个城市,自爆机器人可以瞬间 引爆,破坏一个目标(结界发生器,或是杰森国大神殿),当然机器人本身也会 一起被破坏。你需要知道:摧毁杰森国所需的最短时间。
Input
第一行两个正整数 N, M。 接下来 M行,每行三个正整数 ui, vi, wi,表示有一条从城市ui到城市 vi的单 向道路,自爆机器人通过这条道路需要 wi的时间。 之后 N 行,每行描述一个城市。首先是一个正整数 li,维持这个城市结界所 使用的结界发生器数目。之后li个1~N 之间的城市编号,表示每个结界发生器的 位置。如果 Li = 0,则说明该城市没有结界保护,保证L1 = 0 。
Output
仅包含一个正整数 ,击败杰森国所需的最短时间。
Sample Input
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
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
Sample Output
5
![](http://www.lydsy.com/JudgeOnline/images/1922.jpg)
HINT
对于 20%的数据,满足 N≤15,M≤50;
对于 50%的数据,满足 N≤500,M≤6,000;
对于 100%的数据,满足 N≤3,000,M≤70,000,1≤wi≤108
。
输入数据保证一定有解,且不会存在维持某个城市结界的结界发生器在这个
城市内部。
连接两个城市的道路可能不止一条, 也可能存在一个城市自己到自己的道路。
题解
首先我们可以看出着就是求最短路,只不过是带了一点限制
对于每一个点,我们记录一下他的到达时间d1和解除结界的时间d2,显然对一个城市i,只有在max{d1[i],d2[i]}之后才能进入。对于d2[i],是所有维持它结界的城市的d1的最大值。想想迪杰斯特拉的处理过程,我们每次找出已经被解封的且进入时间最早的点对其他的点进行更新,最后输出max{d1[n],d2[n]}
看看代码就能明白了
还有,有重边啊QAQ
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 /************************************************************** 2 Problem: 1922 3 User: 1090900715 4 Language: Pascal 5 Result: Accepted 6 Time:2136 ms 7 Memory:47244 kb 8 ****************************************************************/ 9 10 program j01; 11 var a:array[0..3100,0..3100]of longint; 12 d1,d2:array[0..3100]of int64; 13 l:array[0..3100,0..3100]of boolean; 14 num:array[0..3100]of longint; 15 bo:array[0..3100]of boolean; 16 n,m,i,j,u,v:longint; 17 w:int64; 18 function min(a,b:int64):int64; 19 begin 20 if a<b then exit(a) else exit(b); 21 end; 22 function max(a,b:int64):int64; 23 begin 24 if a>b then exit(a) else exit(b); 25 end; 26 begin 27 readln(n,m); 28 fillchar(a,sizeof(a),$3f); 29 for i:=1 to m do 30 begin 31 readln(u,v,w); 32 a[u,v]:=min(a[u,v],w); 33 end; 34 fillchar(l,sizeof(l),0); 35 for i:=1 to n do 36 begin 37 read(num[i]); 38 for j:=1 to num[i] do 39 begin 40 read(u); 41 l[u,i]:=true; 42 end; 43 end; 44 fillchar(d1,sizeof(d1),$3f); 45 fillchar(d2,sizeof(d2),0); 46 fillchar(bo,sizeof(bo),0); 47 d1[1]:=0; 48 for i:=1 to n do 49 begin 50 u:=0;w:=$3f3f3f3f3f3f3f3f; 51 for j:=1 to n do 52 if (num[j]=0)and(bo[j]=false)and(max(d1[j],d2[j])<w) then 53 begin 54 u:=j; 55 w:=max(d1[j],d2[j]); 56 end; 57 if u=0 then break; 58 bo[u]:=true; 59 for j:=1 to n do 60 begin 61 if l[u,j] then 62 begin 63 dec(num[j]); 64 d2[j]:=max(w,d2[j]); 65 end; 66 d1[j]:=min(d1[j],w+a[u,j]); 67 end; 68 end; 69 writeln(max(d1[n],d2[n])); 70 end. 71