冲刺NOIP2015提高组复赛模拟试题(五) 3.破坏基地

3.破坏基地

描述 Description

在Z国和W国之间一直战火不断。 好不容易,W国的间谍把完整的Z国的军事基地的地图到手了。 于是W国决定再次出击,一举击破Z国的防线。 W国认真研究了Z国的地形,发现Z国有N个军事基地,我们不妨编号成1..N,而且经过深刻研究,发现1号军事基地是资源补给基地,而N号军事基地是前线。 由于地形的缘故,只有M对军事基地两两可达,当然是有距离的。 此时W国的弹头紧缺,当下的弹头只能去毁灭一个军事基地。当然了,最重要的就是毁灭一个军事基地,使得资源补给基地与前线的最短距离发生变化。但是Z国也不是白痴,他们的资源补给基地与前线有着极高的防御力,所以W国只能去炸掉其余的N-2个基地,当然炸掉某个基地后,这个基地就不可达了。 于是问题就来了,炸掉哪些基地后会使得资源补给基地与前线的最短距离发生变化呢?注:假若炸掉某个基地后,1号基地和N号基地不连通,那么我们也认为他们的最短距离发生了变化。

输入格式 InputFormat

输入数据第一行是两个正整数N,M,意义如题所述。 接下来M行,每行包括三个正整数x,y,d,表示有一条边连接x、y两个地点,其距离为d。数据保证图是连通的。

输出格式 OutputFormat

输出数据的第一行包含一个整数K,表示有K个基地可毁灭,且毁灭其中任意一个后,资源补给基地与前线的最短距离发生变化。接下来K行,每行输出一个军事基地的编号,要求编号递增。 在wyl8899神犇的率领下,W国必胜!!! 因此一定不会存在K=0的情况。

样例输入 SampleInput [复制数据]

6 7

1 2 3

1 5 2

2 3 5

2 4 3

2 5 4

2 6 5

3 4 2

样例输出 SampleOutput [复制数据]

1

2

数据范围和注释 Hint

对于30%的数据,N<=100,M<=1,000;对于60%的数据,N<=2,000,M<=20,000; 对于100%的数据,N<=10,000,M<=100,000,1<=d<=10,000;

时间限制 TimeLimitation

1s
解:spfa+记录前驱(输出路径)

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<queue>
 5 #include<algorithm>
 6 #define sc(x) scanf("%d",&x)
 7 #define man 100010
 8 using namespace std;
 9 struct point
10 {
11     int next,to,cost;
12     }e[man*2];
13 int n,num,m,head[man*2],pre[man];
14 int p[man],tot=0;
15 long long dis[man];
16 bool vis[man];
17 void add(int from,int to,int cost)
18 {
19     e[++num].next=head[from];
20     e[num].to=to;
21     e[num].cost=cost;
22     head[from]=num;
23     }
24 queue<int>q;
25 void spfa(int s)
26 {
27     for(int i=1;i<=n;i++)
28         dis[i]=999999999;
29     memset(vis,0,sizeof(vis));
30     q.push(s);
31     dis[s]=0;
32     vis[s]=1;
33     while(!q.empty())
34     {
35         int u=q.front();
36         q.pop();
37         vis[u]=0;
38         for(int i=head[u];i;i=e[i].next)
39         {
40             int to=e[i].to;
41             if(dis[to]>dis[u]+e[i].cost)
42             {
43                 dis[to]=dis[u]+e[i].cost;
44                 pre[to]=u;
45                 if(!vis[to])
46                 {
47                     vis[to]=1;
48                     q.push(to);
49                     }
50                 }
51             }
52         }
53     }
54 void print(int x)
55 {
56     if(pre[x]==x)
57         return;
58     print(pre[x]);
59     p[++tot]=x;
60     }
61 int main()
62 {   freopen("destroy.in","r",stdin);
63     freopen("destroy.out","w",stdout);
64     sc(n);sc(m);
65     for(int x,y,z,i=1;i<=m;i++)
66     {
67         sc(x);sc(y);sc(z);
68         add(x,y,z);
69         add(y,x,z);
70         }
71     spfa(1);
72     pre[1]=1;
73     print(n);
74     sort(p+1,p+tot+1);
75     printf("%d
",tot-1);
76     for(int i=1;i<=tot;i++)
77     {   if(p[i]==1||p[i]==n)
78             continue;
79         printf("%d
",p[i]);}
80     return 0;
81     }
欢迎大家吐槽或评论,如要转载请注明地址,谢谢~(虽然不一定有人能看到。。。)
原文地址:https://www.cnblogs.com/Slager-Z/p/7441829.html