今天开始图论的最短路的最后复习,今天自己手打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开发之--开发中可能会用到的一些函数

    rand() ----随机数 abs() / labs() ----整数绝对值 fabs() / fabsf() / fabsl() ----浮点数绝对值 floor() / floorf() / f ...

  2. iOS 图片加载速度极限优化—FastImageCache解析

    FastImageCache是Path团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动起来更顺畅,来看看它是怎么做的.优化点iOS从磁盘加载一张图片,使用UIImageVIew ...

  3. 使用HttpClient访问url的工具类

    maven依赖jar包配置: <dependency> <groupId>org.apache.httpcomponents</groupId> <artif ...

  4. Ubuntu12.04编译Android2.3.4

    Ubuntu12.04编译Android2.3.4 1.下载Ubuntuubuntu-12.04-dvd-i386.iso2.使用U盘安装,启动盘制作用unetbootin-windows-568工具 ...

  5. Spring系列之IOC容器

    一.概述 IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化.定位.配置应用程序中的对象及建立这些对象之间的依赖.应用程序无需直接在代码中new 相关的对象,应用程序由IOC容器进行组装.在S ...

  6. 【linux系列】Centos下安装mysql数据库

    前言 为了测试方便,通常我们会自己安装数据库,以下是在Centos上安装Mysql的操作. 一.检查自己是否安装了MySQL数据库 [root@s201 /home/mysql]#rpm -qa |g ...

  7. JS-缓冲运动基础结构

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. MFC 常见问题

    一 常见变量获得 CDC * cDc=GetDC(); HDC m_Screenhdc = this->GetDC()->m_hDC; //  整个窗口客户区的坐标 this->Ge ...

  9. C# 程序自动重启的解决方法

    很多时候,我们有这样的场景,需要让程序自动重启,有很多种方法,比如用微软自带提供的方法,或者自己开辟新的线程重新调用.下面简单介绍两种方法. 方法一. 使用方法Application.Restart( ...

  10. 使用PowerShell替代WinDbg在高分辨率笔记本下调试、排错

    最近换新的开发笔记本,分辨率较高发现部分应用在High DPI下几乎没法用.比较纠结的就是WinDbg,频繁切换分辨率.显示文字大小影响工作节奏.幸好PowerShell在High DPI下效果不错. ...