知识点
负环
负环,顾名思义,就是一张图上的一个边权和为负数的环。
负权边在最短路或此类问题上,会导致一些在正权图上能正常运行的算法失效。
处理负边权,可以采用Flody算法,Bellman-Ford算法,和优化过的Bellman-Ford算法:SPFA
在竞赛中,大多数题目会卡SPFA算法,但碰到存在负边权的时候,SPFA算法就是正解了。
SPFA算法核心代码:
queue <int> q;
inline bool SPFA()
{
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
//数组清零
while(!q.empty()) q.pop(); //清空队列
q.push(1); //先加入结点,然后记录
dis[1]=0; //记录路径
vis[1]=1; //统计该点已经搜索过
while(!q.empty())
{
int u=q.front(); //取出队首元素
vis[u]=0; //标记该点
q.pop(); //弹出该点
for(int i=head[u];i!=-1;i=edge[i].next) //链式前向星查找每个点的方式
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].w) //松弛操作
{
dis[v]=dis[u]+edge[i].w;
ans[v]=ans[u]+1; //统计已经走过的路径
if(ans[v]>=n) //路径数大于n,存在点被第二次经过
{
return 1;
}
if(!vis[v]) //如果到达的点不在队列里
{
q.push(v); //将下一个点进队
vis[v]=1;
}
}
}
}
return 0; //没有负环
}
模板题:洛谷 P3385 【模板】负环