BZOJ 2622 深入虎穴 题解

怎么会有这么优秀的脑斧

首先题目把题意写得很清楚了,SPFA不会被卡但我没写,就是求一个次小生成树嘛。

考虑Dijkstra,那么就需要修改一小部分:

  我们用dis[0][x],dis[1][x]表示从某一个出口到x这个点的最短路与次短路,在读入出口的时候将出口的dis都设为0,压入优先队列,用次短路更新相邻点的最短路与次短路,最后的dis[1][0]就是我们要的答案。

代码如下:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define HA 19260817
 4 #define ERP(i,a) for(int i=head[(a)];i+1;i=e[i].nxt)
 5 #define REP(i,a,b) for(int i=(a),edd=(b);i<=edd;++i)
 6 #define DRP(i,a,b) for(int i=(a),edd=(b);i>=edd;--i)
 7 using namespace std;
 8 const int maxn=1e5+5,maxm=1e6+5,inf=0x7fffffff;
 9 
10 inline int read(){
11     char ch=getchar();
12     int r=0,s=1;
13     while(ch>57||ch<48)s=ch==45?0:s,ch=getchar();
14     while(ch>=48&&ch<=57)r=r*10+ch-48,ch=getchar();
15     return s?r:-r;
16 }
17 
18 priority_queue< pair< int , int > > q;
19 struct edge{int to,nxt,w;}e[maxm<<1];
20 int n,m,k,cnt;
21 int esp[maxn],dis[2][maxn],vis[maxn],head[maxn];
22 
23 void add(int u,int v,int w){e[++cnt]=(edge){v,head[u],w},head[u]=cnt;return;}
24 
25 void init(){
26     memset(head,-1,sizeof(head));//初始化,因为洞穴标号是从零开始的
27     n=read(),m=read(),k=read();
28     for(int i=0;i<n;++i)dis[0][i]=dis[1][i]=inf;
29     for(int i=1,x,y,z;i<=m;++i)x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
30     for(int i=1;i<=k;++i)esp[i]=read(),q.push(make_pair(0,esp[i])),dis[1][esp[i]]=dis[0][esp[i]]=0;
31     return;
32 }
33 
34 void Dijkstra(){//就是个普通的优先队列优化Dijkstra
35     int x,y,z;
36     while(q.size()){
37         x=q.top().second,q.pop();
38         if(vis[x])continue;
39         vis[x]=1;
40         for(int i=head[x];i+1;i=e[i].nxt){
41             y=e[i].to,z=e[i].w;
42             if(!vis[y]){
43                 if(dis[1][y]>dis[1][x]+z){//更新最短路和次短路
44                     if(dis[0][y]>dis[1][x]+z){
45                         dis[1][y]=dis[0][y];
46                         dis[0][y]=dis[1][x]+z;
47                     }
48                     else dis[1][y]=dis[1][x]+z;
49                     q.push(make_pair(-dis[1][y],y));
50                 }
51             }
52         }
53     }
54     return;
55 }
56     
57 int main(){
58     freopen("t.in","r",stdin);
59     init();
60     Dijkstra();
61     printf("%d\n",dis[1][0]);
62     return 0;
63 }

亲测比SPFA快1000ms左右

 

posted @ 2018-10-27 16:36  绥棱泷Narcissus  阅读(338)  评论(7编辑  收藏  举报