其他分享
首页 > 其他分享> > 348.大陆争霸「SDOI2010」

348.大陆争霸「SDOI2010」

作者:互联网

#348.大陆争霸「SDOI2010」

#348. 大陆争霸「SDOI2010」

内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较

题目描述

在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国。两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉泽。 幻想历 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行,每行三个正整数 ui, vi, wi,表示有一条从城市ui到城市vi的单向道路,自爆机器人通过这条道路需要wi的时间。 之后 N 行,每行描述一个城市。首先是一个正整数 Li,维持这个城市结界所 使用的结界发生器数目。之后Li1~N 之间的城市编号,表示每个结界发生器的 位置。如果Li=0,则说明该城市没有结界保护,保证L1=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

样例说明

1922.jpg

数据范围与提示

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

题解

其实这道题目是Dijkstra算法的基础运用~稍带一点拓扑;

这是一道带有限制条件的单源最短路,求解这道题则可以这样做:

另附代码:

编号题目状态分数总时间内存代码 / 答案文件
#23400 #348. 大陆争霸「SDOI2010」 Accepted 100 54 ms 1236 K C++ 17 / 1.9 K
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
//快读
unsigned int read() {
    int x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x*=10,x+=ch-'0',ch=getchar();
    return x;
}
//变量声明
int N,M,L[3005];
vector<int> protect[3005];
//图
int head[3005],ver[70005],edge[70005],Next[70005],tot=0;
void add(int u,int v,int weight) {
	ver[++tot]=v;
    edge[tot]=weight;
	Next[tot]=head[u];
	head[u]=tot;
}
//dijkstra算法
int dis1[3005],dis2[3005],vis[3005];
priority_queue<pair<int,int> > q;
void dijkstra() {
    memset(dis1,0x3f,sizeof(dis1));
    memset(vis,0,sizeof(vis));
    dis1[1]=0;
    q.push(make_pair(0,1));
    while(!q.empty()) {
        int now=q.top().second;
        q.pop();
        if(vis[now]) continue;
        vis[now]=1;
        //dis1的处理
        for(int i=head[now];i;i=Next[i]) {
            int to=ver[i],w=edge[i];
            if(dis1[to]>max(dis1[now],dis2[now])+w) {
            	dis1[to]=max(dis1[now],dis2[now])+w;
            	if(!L[to]) q.push(make_pair(-max(dis1[to],dis2[to]),to));
			}
        }
        //dis2的处理
        for(int i=0;i<protect[now].size();i++) {
        	int target=protect[now][i];
        	L[target]--;
        	dis2[target]=max(max(dis1[now],dis2[now]),dis2[target]);
        	if(!L[target]) q.push(make_pair(-max(dis1[target],dis2[target]),target));
		}
    }
}
//执行
int main() {
    N=read();M=read();
    for(int i=1;i<=M;i++) {
        int u_i=read(),v_i=read(),w_i=read();
        if(u_i!=v_i) add(u_i,v_i,w_i);
    }
    for(int i=1;i<=N;i++) {
        L[i]=read();
        for(int j=1;j<=L[i];j++) {
            int num=read();
            protect[num].push_back(i);
        }
    }
    dijkstra();
    int ans=max(dis1[N],dis2[N]);
    printf("%d\n",ans);
    return 0;
}
子任务 #1 Accepted 得分:100 测试点 #1 Accepted 得分:100 用时:9 ms 内存:1088 KiB

输入文件(1.in)

3000 52999
1 2 4384713
1 3 2976483
1 4 42433
1 5 9094931
1 6 1716347
1 7 843796
1 8 1972383
1 9 4170
<791164 bytes omitted>

答案文件(1.out)

7542

用户输出

7542

系统信息

Exited with return code 0
测试点 #2 Accepted 得分:100 用时:2 ms 内存:352 KiB

输入文件(2.in)

500 1499
1 2 3557269
1 3 7872037
1 4 6280913
1 5 3511951
1 6 1922146
1 7 7330055
1 8 5717005
1 9 321
<21673 bytes omitted>

答案文件(2.out)

2447629

用户输出

2447629

系统信息

Exited with return code 0
测试点 #3 Accepted 得分:100 用时:2 ms 内存:228 KiB

输入文件(3.in)

10 30
7 5 385
4 10 809
10 6 846
4 3 742
9 10 117
1 3 32
8 6 750
9 10 928
1 7 451
8 2 451
10 2 73
1 1
<185 bytes omitted>

答案文件(3.out)

927

用户输出

927

系统信息

Exited with return code 0
测试点 #4 Accepted 得分:100 用时:2 ms 内存:224 KiB

输入文件(4.in)

15 51
1 2 774781
1 3 4677433
1 4 8331780
1 5 8304787
1 6 7989193
1 7 7041916
1 8 9261749
1 9 854448

<471 bytes omitted>

答案文件(4.out)

1957

用户输出

1957

系统信息

Exited with return code 0
测试点 #5 Accepted 得分:100 用时:8 ms 内存:1028 KiB

输入文件(5.in)

3000 52999
1 2 627116
1 3 9597816
1 4 5777971
1 5 6144797
1 6 1470809
1 7 6321394
1 8 4798286
1 9 29
<791778 bytes omitted>

答案文件(5.out)

7857

用户输出

7857

系统信息

Exited with return code 0
测试点 #6 Accepted 得分:100 用时:2 ms 内存:356 KiB

输入文件(6.in)

100 1200
35 68 42
25 70 501
63 59 479
46 6 465
62 28 282
43 96 492
92 37 828
54 3 605
22 83 293
96 1
<13149 bytes omitted>

答案文件(6.out)

2920

用户输出

2920

系统信息

Exited with return code 0
测试点 #7 Accepted 得分:100 用时:8 ms 内存:1036 KiB

输入文件(7.in)

3000 52999
1 2 333250
1 3 2176941
1 4 7367336
1 5 4671986
1 6 9354970
1 7 9046673
1 8 9458566
1 9 39
<790903 bytes omitted>

答案文件(7.out)

10763

用户输出

10763

系统信息

Exited with return code 0
测试点 #8 Accepted 得分:100 用时:9 ms 内存:1236 KiB

输入文件(8.in)

3000 62999
1 2 5601606
1 3 7742821
1 4 8465591
1 5 2614717
1 6 4491093
1 7 3310721
1 8 4651502
1 9 7
<900322 bytes omitted>

答案文件(8.out)

4844

用户输出

4844

系统信息

Exited with return code 0
测试点 #9 Accepted 得分:100 用时:4 ms 内存:328 KiB

输入文件(9.in)

500 5499
1 2 4911877
1 3 4513935
1 4 5205623
1 5 6299491
1 6 7447065
1 7 221209
1 8 6674449
1 9 3636
<67429 bytes omitted>

答案文件(9.out)

1863

用户输出

1863

系统信息

Exited with return code 0
测试点 #10 Accepted 得分:100 用时:8 ms 内存:1024 KiB

输入文件(10.in)

3000 47999
1 2 9517163
1 3 5071685
1 4 6900534
1 5 4372056
1 6 6849121
1 7 4046390
1 8 2648771
1 9 4
<727288 bytes omitted>

答案文件(10.out)

97686

用户输出

97686

系统信息

Exited with return code 0

 

标签:争霸,dis2,杰森国,dis1,SDOI2010,ms,结界,100,348
来源: https://www.cnblogs.com/oi-zzy/p/gdoi-348.html