图论里面有一个致命的东西,那就是负权边,现在我会的算法中能解决负边的只有$O(n^3)$的$Floyd$......遇到负权边我们还是要向SPFA伸手
↑↑正文分割线
我在寒假集训Day1的笔记里曾提到这个东西,松弛:$dis[v]=\min(dis[v],dis[u]+dis(u,v))$
for (int k=1;k<=n-1;k++)//n是顶点的数量
for (itn i=1;i<=m;i++)//m是边的数量
if (dis[v[i]]>dis[u[i]]+w[i])//u[i]和v[i]是边的两个顶点
dis[v[i]]=dis[u[i]]+w[i];//w[i]是边的费用
#include <iostream>
#include <queue>
using namespace std;
const int inf=2147483647;
const int maxn=10005;
int n,m,b,e=0,i,j;
int dis[maxn],head[500005];
bool vis[maxn];
struct node
{
int next,to,dis;
}edge[500005];
queue<int> q;
void addedge(int from,int to,int dis)
{
edge[++e].next=head[from];
edge[e].dis=dis;
edge[e].to=to;
head[from]=e;
}
void spfa()
{
for(i=1;i<=n;i++) dis[i]=inf;
dis[b]=0;
q.push(b),vis[b]=1;
while(!q.empty())
{
int begin=q.front();
q.pop();
for(i=head[begin];i;i=edge[i].next)
{
if(dis[edge[i].to]>dis[begin]+edge[i].dis)
{
dis[edge[i].to]=dis[begin]+edge[i].dis;
if(!vis[edge[i].to])
{
vis[edge[i].to]=1;
q.push(edge[i].to);
}
}
}
vis[begin]=0;
}
}
int main()
{
cin>>n>>m>>b;
for(int i=1; i<=m; i++)
{
int f,t,d;
cin>>f>>t>>d;
addedge(f,t,d);
}
spfa();
for(int i=1; i<=n; i++)
if(b==i) cout<<0<<' ';
else cout<<dis[i]<<' ';
return 0;
}
咕咕咕......(等待更新QAQ)更新分割线↓↓↓
Void SPFA(Node){
Instack[Node]=true;
For (NOde,v) ∈ E
If dis[Node]+edge(Node,v)<dis[v] then{
dis[v]=dis[Node]+edge(Node,v);
If not Instack[v] then
SPFA();
Else
Return;
}
Instack[Node]=false;
}
咕咕咕.....(等待更新)
本文作者:Snowflake_Pink
本文链接:https://snowflake.pink/archives/12/
最后修改时间:2024-09-30 23:18:19
本站未注明转载的文章均为原创,并采用 CC BY-NC-SA 4.0 授权协议,转载请注明来源,谢谢!