来源1:https://www.luogu.org/problemnew/show/P3371(spfa能过)
来源2:https://www.luogu.org/problemnew/show/P4779(spfa超时)
spfa更多解释参考https://blog.csdn.net/scutbenson/article/details/78447575
代码献上。。。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
struct node
{
int y,weight;
};
const int maxSize=100000,maxValue=0x7fffffff;
int n,m,s;
int dis[maxSize+5],vis[maxSize+5]; //vis 判断是否在队列内
vector <node> M[maxSize+5];
queue <int> q;
void spfa()
{
int i,x;
node n1;
while (!q.empty())
{
x=q.front(); q.pop();
vis[x]=0;
for (i=0;i<M[x].size();i++)
{
n1=M[x][i];
if (dis[x]+n1.weight<dis[n1.y])
{
dis[n1.y]=dis[x]+n1.weight;
if (vis[n1.y]==0)
{
q.push(n1.y);
vis[n1.y]=1;
}
}
}
}
}
int main()
{
int i,x,y,z;
node n1;
freopen("a.txt","r",stdin);
scanf("%d%d%d",&n,&m,&s);
for (i=1;i<=n;i++)
dis[i]=maxValue;
memset(vis,0,sizeof(vis));
for (i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
n1.y=y; n1.weight=z;
M[x].push_back(n1);
}
vis[s]=1; q.push(s); dis[s]=0;
spfa();
for (i=1;i<=n;i++)
printf("%d ",dis[i]);
return 0;
}
堆优化过后:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
struct node
{
int y,weight;
friend bool operator < (node n1,node n2) //定义一个函数!
{
return n1.weight>n2.weight; //"<"为从大到小,">" 为从小到大
}
};
const int maxSize=100000,maxValue=0x7fffffff;
int n,m,s;
int dis[maxSize+5],vis[maxSize+5]; //vis 判断是否在队列内
vector <node> M[maxSize+5];
priority_queue <node> q; //小根堆 top()
void spfa()
{
int i,x;
node n1;
while (!q.empty())
{
x=q.top().y; q.pop();
vis[x]=0;
for (i=0;i<M[x].size();i++)
{
n1=M[x][i];
if (dis[x]+n1.weight<dis[n1.y])
{
dis[n1.y]=dis[x]+n1.weight;
if (vis[n1.y]==0)
{
q.push(n1);
vis[n1.y]=1;
}
}
}
}
}
int main()
{
int i,x,y,z;
node n1;
freopen("a.txt","r",stdin);
scanf("%d%d%d",&n,&m,&s);
for (i=1;i<=n;i++)
dis[i]=maxValue;
memset(vis,0,sizeof(vis));
for (i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&z);
n1.y=y; n1.weight=z;
M[x].push_back(n1);
}
n1.y=s; n1.weight=0;
vis[s]=1; q.push(n1); dis[s]=0;
spfa();
for (i=1;i<=n;i++)
printf("%d ",dis[i]);
return 0;
}