https://www.luogu.org/problemnew/show/P2865

看到题解好多dijkstra,作为一名钟爱于spfa的蒟蒻看不下去了。

有些spfa要跑两边,代码量要曾长好多(虽然复制),而且还慢。

下面开始我的表演:

首先看清楚题意:题目说的是从n点往回走(因为双向边,所以好多人注意到也过了)

接着明确一个数组:

d[i][0]表示到i点的最短路

d[i][1]表示到i点的次短路

初始化数组,d[n][0]=0,d[n][1]=INF,其他的也都是INF;

然后将点进入队列开始,进行对其他点的更改。

记当前节点编号为u,目前所连边的编号为v。

我们将判断分为两块

(1)d[u][0]对于v点的影响。

(2)d[u][1]对于v点的影响。

#### (1)

如果$$d[u][0]+dis[u,v]<d[v][0]$$,也就是说足影响v点,那么此时的次短路变成了更新前的最短路,最短路更新。

如果
$$d[v][0]<=d[u][0]+dis[u,v]$$

$$d[v][0]>=d[u][0]+dis[u,v]$$

就是说不足以影响最短路,却可以影响次短路,能更新自然更新。

#### (2)

再开始判断d[u][1]对v点的影响

前边(1)部分先更新的最短路。

如果足矣更新最短路:那么到u点的最短路一定小于到u点的次短路,所以用d[u][0]一定更优。

如果没有更新:那么既然最短路都不能更新了,次短路还有啥用。

总的来说对v点最短路这一块理解就好,木有代码。

对于次短路我们要判断一下是否更新。

注意注意:以上判断都需要注意次短路严格小于最短路。

所以:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
struct ahah{
int nxt,to,dis;
}edge[];
int n,m;
int head[],tot;
void add(int x,int y,int z)
{
edge[++tot].nxt=head[x],edge[tot].to=y,edge[tot].dis=z,head[x]=tot;
}
int d[][];
bool vis[];
queue <int> que;
int read()
{
int sum=,fg=; char c=getchar();
while(c<''||c>''){if(c=='-')fg=-;c=getchar();}
while(c>=''&&c<=''){sum=sum*+c-'';c=getchar();}
return sum*fg;
}
void spfa(int s)
{
memset(d,0x7f,sizeof(d));
que.push(s);vis[s]=;
d[s][]=;
while(!que.empty())
{
int u=que.front();
vis[u]=;que.pop() ;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(d[v][]>d[u][]+edge[i].dis)
{
d[v][]=d[v][];
d[v][]=d[u][]+edge[i].dis;
if(!vis[v])vis[v]=,que.push(v);
}
if(d[v][]>d[u][]+edge[i].dis&&d[u][]+edge[i].dis>d[v][])
{
d[v][]=d[u][]+edge[i].dis;
if(!vis[v])vis[v]=,que.push(v);
}
if(d[v][]>d[u][]+edge[i].dis)
{
d[v][]=d[u][]+edge[i].dis;
if(!vis[v])vis[v]=,que.push(v);
}
}
}
}
int main()
{
int x,y,z;
n=read();m=read();
for(int i=;i<=m;i++)
{
x=read(),y=read(),z=read();
add(x,y,z);add(y,x,z);
}
spfa(n);
printf("%d",d[][]);
}

最新文章

  1. 将项目导入eclipse中出现的jsp页面报错解决
  2. html制作,点击文字超链接显示文本框,再点击文字超链接隐藏文本框
  3. C++注册表操作
  4. JavaScript---DOM文档
  5. PHP 定时任务|Cron
  6. visio
  7. poj1276--Cash Machine(多背包被判刑了)
  8. Controller与Action
  9. JDBC连接数据库实现删除功能
  10. iOS设置圆角的常用方法
  11. IAR map 文件报告与Flash 大小关系
  12. dpkg:错误:正在解析文件 &#39;/var/lib/dpkg/updates/0014&#39; 第 0 行附近:在字段名 #padding 中有换行符问题的解决方法
  13. BOvW简介
  14. 通信原理之UDP协议(四)
  15. OL6.3 设置本地yum源
  16. MySQL——约束(constraint)详解
  17. vue--获取监听获取radius的改变
  18. 使用ngxtop实时监控nginx
  19. java中的互斥锁和信号量的区别
  20. C#中ReferenceEquals和Equals的区别

热门文章

  1. E20170429-hm
  2. hdoj2571【DP基础】
  3. iOS UITableView设置tableHeaderView时发生约束错误 UIView-Encapsulated-Layout-Height UIView-Encapsulated-Layout-Width
  4. PostgreSQL - psql的使用与退出
  5. c 浮点科学计数法
  6. CSS选择器优先级【转】
  7. HTML中div的悬浮标题
  8. SpringCloud开发学习总结(七)—— 声明式服务调用Feign(二)
  9. 144 Binary Tree Preorder Traversal 二叉树的前序遍历
  10. python中函数参数