[SPFA] BZOJ 2622 [2012国家集训队测试]深入虎穴 & BZOJ 2617 [Ioi2011]crocodile
2016-04-13 10:49
393 查看
题解:http://blog.csdn.net/wzq_QwQ/article/details/47997617
其实总体东西就是个SPFA,不过这里面我们需要做一些改动。
这只老虎是DP老虎,他每次会占据你的最优方案。
所以使得你只能用次优方案来更新最优方案以及次优方案。
这就是SPFA的路子。
但是这个路子并不够。
让我们考虑一个点只有一个儿子的时候。
他可能会扫一圈后第一次让他的儿子更新一次答案。
这时候是有最短路而并没次短路的。
但是您肯定会更新一下它的儿子信息。
这时候儿子又会来更新这个点。
那么如果按照咱们的模拟过程,此时儿子就会更新次短距离以及最短距离。
但是显然,这个点是没有次短距离的。
所以如果给这个点更新了次短距离,那么这个点再向上走就会影响答案。
所以这种情况要避免。
具体怎么避免?
就是记录上一次它是被谁更新的,如果下次是同一点,那么就不更新次短距离。
其实总体东西就是个SPFA,不过这里面我们需要做一些改动。
这只老虎是DP老虎,他每次会占据你的最优方案。
所以使得你只能用次优方案来更新最优方案以及次优方案。
这就是SPFA的路子。
但是这个路子并不够。
让我们考虑一个点只有一个儿子的时候。
他可能会扫一圈后第一次让他的儿子更新一次答案。
这时候是有最短路而并没次短路的。
但是您肯定会更新一下它的儿子信息。
这时候儿子又会来更新这个点。
那么如果按照咱们的模拟过程,此时儿子就会更新次短距离以及最短距离。
但是显然,这个点是没有次短距离的。
所以如果给这个点更新了次短距离,那么这个点再向上走就会影响答案。
所以这种情况要避免。
具体怎么避免?
就是记录上一次它是被谁更新的,如果下次是同一点,那么就不更新次短距离。
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define V G[p].v using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } struct edge{ int u,v,w; int next; }; edge G[2000005]; int head[100005],inum; inline void add(int u,int v,int w,int p){ G[p].u=u; G[p].v=v; G[p].w=w; G[p].next=head[u]; head[u]=p; } int n,m,K; int pre[100005]; int dis[100005],sec_dis[100005]; const int ND=1000005; int Q[1000005],l,r; int ins[100005]; inline void SPFA() { memset(dis,0x3f,sizeof(dis)); memset(sec_dis,0x3f,sizeof(sec_dis)); l=r=-1; int u; for (int i=1;i<=K;i++) { read(u); u++; dis[u]=sec_dis[u]=0; Q[(++r)%ND]=u; ins[u]=1; } while (l!=r) { u=Q[(++l)%ND]; ins[u]=0; for (int p=head[u];p;p=G[p].next) { if(sec_dis[u]+G[p].w<=dis[V]) { if(pre[V]!=u) sec_dis[V]=dis[V]; dis[V]=sec_dis[u]+G[p].w; pre[V]=u; if(!ins[V]) Q[(++r)%ND]=V,ins[V]=1; } else if(sec_dis[u]+G[p].w<sec_dis[V]) { sec_dis[V]=sec_dis[u]+G[p].w; if(!ins[V]) Q[(++r)%ND]=V,ins[V]=1; } } } } int main() { int iu,iv,iw; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); read(K); for (int i=1;i<=m;i++) { read(iu); read(iv); read(iw); iu++; iv++; add(iu,iv,iw,++inum); add(iv,iu,iw,++inum); } SPFA(); printf("%d\n",sec_dis[1]); }
相关文章推荐
- 函数后面加const修饰
- cv1.0入门
- String,StringBuffer与StringBuilder的区别
- 单例模式的八种写法比较
- "undefinedreference to '__gxx_personality_v0' " 错误
- JAVA常用文件工具类
- 修复/lib/ld-linux.so.2: bad ELF interpreter: No such file or directory问题
- [转载]OpenGL矩阵变换 一篇很好的译文
- 数据结构(java语言描述)哈夫曼编码
- 阿里云上Docker Compose部署wordpress
- Python future模块小例子
- 导出网页中的table到excel
- android fragment取消预加载
- CMD指令(不定期更新)
- Codeforce 118D: Caesar's Legions
- 欢迎使用CSDN-markdown编辑器
- URL
- 基于Calcite Elasticsearch实现的SQL ON ES方案设想
- 轻松把玩HttpClient之配置ssl,采用绕过证书验证实现https
- Ubuntu下配置C++编辑器VIM