今天开始图论的最短路的最后复习,今天自己手打spfa虽然看了一眼书,但是也算是自己打出来的,毕竟很久没打了,而且还是一遍a代码下来15min左右就搞完了,成就感++。所以呢来篇博客记录一下。

香甜的黄油,当年做的时候吃了不少苦头现在完全会打了,下面是当时我的代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<ctime>
#include<iostream>
#include<string>
using namespace std;
const int maxn=,inf=;
int n,p,c,a,b,d,t,dist[maxn],s1[maxn],inq[maxn];
vector<int>g[maxn],w[maxn]; void spfa(int s)
{
queue<int>a;//一个队列a
for(int i=;i<=p;i++)//循环4个牧场都附极大值
dist[i]=inf;
memset(inq,,sizeof(inq));//清空inp dist[s]=;//把到当前的牧场距离设为0,毕竟是自己到自己
a.push(s);//进队
inq[s]=;//使其为1 while(!a.empty())//如果队列不为空
{
int i=a.front();//返回队首元素
a.pop();//弹出队首
inq[i]=;//使其为0
for(int k=;k<g[i].size();k++)//当前的牧场和其余的牧场相连
{
int j=g[i][k];//取i到j的牧场号询问其距离
if(dist[i]+w[i][k]<dist[j])//如果当前距离和i到k的距离小于j松弛操作
{
dist[j]=dist[i]+w[i][k];//松弛
if(inq[j]!=) continue;//询问是否在队列之中
inq[j]=;//不在的话再次标记
a.push(j);//使当前的点进队好像bfs但不是bfs多次进队
}
}
}
} int main()
{
//freopen("1.in","r",stdin);
scanf("%d%d%d",&n,&p,&c);//n为奶牛所在的牧场号,p为4个牧场,c为5个牧场的关系
memset(s1,,sizeof(s1));//s1存的是奶牛的牧场位置;
for(int i=;i<=n;i++)
{
scanf("%d",&t);//牛
s1[t]++;//牧场
}
for(int i=;i<=c;i++)
{
scanf("%d%d%d",&a,&b,&d);//a与b之间的距离为d
g[a].push_back(b);//扩边
g[b].push_back(a);
w[a].push_back(d);//二次扩边
w[b].push_back(d);
}
int ans=inf;//附最大值
for(int i=;i<=p;i++)//枚举每一个牧场为起点
{
spfa(i);//当黄油放在第i个牧场时来一个一个判断;跑距离
int sum=;
for(int j=;j<=p;j++)
{
if(!s1[j]) continue;
sum+=dist[j]*s1[j]; //计算奶牛到牧场的距离和
}
ans=min(sum,ans); //取最小值
}
printf("%d",ans);
return ;
}

注释很多很多,主要因为当时的不理解。

下面是本人今天的代码!!!

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<map>
#define inf 10000000
using namespace std;
const int maxn=;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int b[maxn],ver[maxn],lin[maxn],nex[maxn],len=,e[maxn],minn=inf,dis[maxn],q[maxn];
bool vis[maxn];
void add(int x,int y,int z)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
e[len]=z;
}
int n,m,k,h,t;
void spfa(int x)
{
memset(vis,,sizeof(vis));
memset(dis,,sizeof(dis));
memset(q,,sizeof(q));
dis[x]=;vis[x]=;q[]=x;
h=,t=;
while(h<=t)
{
int tn=q[++h];vis[tn]=;
for(int i=lin[tn];i;i=nex[i])
{
int tmp=ver[i];
if(dis[tn]+e[i]<dis[tmp])
{
dis[tmp]=dis[tn]+e[i];
if(vis[tmp]!=)
{
q[++t]=tmp;
vis[tmp]=;
}
}
}
}
}
int main()
{
freopen("1.in","r",stdin);
k=read();m=read();n=read();
memset(b,,sizeof(b));
for(int i=;i<=k;i++){int x;x=read();b[x]++;}
for(int i=;i<=n;i++)
{
int x,y,z;
x=read();y=read();z=read();
add(x,y,z);
add(y,x,z);
}
for(int i=;i<=m;i++)
{
int ans=;
spfa(i);
for(int j=;j<=m;j++)
{
if(b[j]!=)
ans+=dis[j]*b[j];
}
minn=min(ans,minn);
}
printf("%d\n",minn);
return ;
}

思路很清晰的打完了哈哈。

莫听穿林打叶声,何妨吟啸且徐行。

图论最短路——spfa的更多相关文章

  1. 图论--最短路--SPFA

    SPFA算法(shortest path faster algorithm)算法是西南交通大学段凡丁于1994年发表的,它在Bellman-ford算法的基础上进行了改进,使其在能够处理待负权图的单元 ...

  2. 图论--最短路--SPFA模板(能过题,真没错的模板)

    [ACM常用模板合集] #include<iostream> #include<queue> #include<algorithm> #include<set ...

  3. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  4. L - Subway(最短路spfa)

    L - Subway(最短路spfa) You have just moved from a quiet Waterloo neighbourhood to a big, noisy city. In ...

  5. 图论:最短路-SPFA

    该算法由Bellman-Ford算法演变过来,首先介绍一下Bellman-Ford算法 最短路最多经过n-1个点,可以用n-1轮松弛操作来得到 ;i<n;i++) d[i]=INF; d[]=; ...

  6. 图论-单源最短路-SPFA算法

    有关概念: 最短路问题:若在图中的每一条边都有对应的权值,求从一点到另一点之间权值和最小的路径 SPFA算法的功能是求固定起点到图中其余各点的的最短路(单源最短路径) 约定:图中不存在负权环,用邻接表 ...

  7. 图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题

    一.Floyd算法 用于计算任意两个节点之间的最短路径. 参考了five20的博客 Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个 ...

  8. 图论算法(三) 最短路SPFA算法

    我可能要退役了…… 退役之前,写一篇和我一样悲惨的算法:SPFA 最短路算法(二)SPFA算法 Part 1:SPFA算法是什么 其实呢,SPFA算法只是在天朝大陆OIers的称呼,它的正统名字叫做: ...

  9. 图论(最短路&最小生成树)

    图论 图的定义与概念 图的分类 图,根据点数和边数可分为三种:完全图,稠密图与稀疏图. 完全图,即\(m=n^2\)的图\((m\)为边数,\(n\)为点数\()\).如: 1 1 0 1 2 1 1 ...

随机推荐

  1. ios开发之 -- NSData 和 NSString , UIImage 等之间的互转

    //NSData转换为UIImage NSData *imageData = [NSData dataWithContentsOfFile: imagePath]; UIImage *image = ...

  2. iOS 使用动态库

    苹果的开放态度 WWDC2014上发布的Xcode6 beta版有了不少更新,其中令我惊讶的一个是苹果在iOS上开放了动态库,在Xcode6 Beta版的更新文档中是这样描述的: Frameworks ...

  3. CouchDB 未授权访问漏洞

    0x00 CouchDB安装 CouchDB官方网站:http://couchdb.apache.org/ 一路Next直到完成安装,打开浏览器并访问以下链接:http://127.0.0.1:598 ...

  4. 第1章 Ansible 简介

    1. Ansible 优点 (1) 易读的语法:Ansible使用playbook作为配置管理脚本,playbook是基于YAML开发的,是一种易于读写的数据格式(2) 远程主机无须安装任何依赖:被A ...

  5. /etc/issue

    /etc/issue 与 /etc/motd 作用一致,都是用于显示欢迎信息,区别在于 /etc/issue 是在 login 提示符之前显示,而 /etc/motd 则在在用户成功登录系统之后显示 ...

  6. mysql存储过程中使用事务

    DROP PROCEDURE IF EXISTS test_sp1 CREATE PROCEDURE test_sp1( ) BEGIN ; ; START TRANSACTION; INSERT I ...

  7. UITableView+FDTemplateLayoutCell源码学习笔记

    本文转载至  http://www.cocoachina.com/bbs/read.php?tid=299773 基本原理是通过缓存每个cell的高度,当tableview回调delegate的hei ...

  8. __declspec(dllimport)与__declspec(dllexport)作用总结

    参考自:http://bbs.csdn.net/topics/330169671 __declspec(dllexport):导出符号,也就是定义需要导出函数的dll中给导出函数的函数声明前面加上导出 ...

  9. JS使用中碰到的一些问题

    settimeout: 1.setTimeout(function () {//这个则会在1秒后进行弹出1 alert(1); }, 1000); 2.setTimeout(alert(1), 100 ...

  10. 【EF框架】使用params参数传值防止SQL注入报错处理

    通过SqlParameter传时间参数,代码如下: var param = new List<SqlParameter>(); param.Add(new SqlParameter(&qu ...