#include<bits/stdc++.h>
#define maxn 10005
using namespace std;
int n,m,s;
int u,v,w;
//边-结构体
struct Edge{
int v,w,next;
}edge[maxn<<1];//乘2以防无向图,有备无患
int head[maxn],cnt,dis[maxn],inqueue[maxn];//统计每个点入队的次数
//记录边的信息
void add(int u,int v,int w)
{
cnt++;
edge[cnt].v=v;//终点
edge[cnt].w=w;//权值
edge[cnt].next=head[u];//指向哪个点
head[u]=cnt;//边数
}
int visit[maxn];//记录是否入对
//主体
bool spfa()
{
memset(dis,0x3f,sizeof(dis));//每个点先直接无穷大
dis[s]=0;//到自己的距离为0
queue<int>q;//创建队列
q.push(s);//起点入队
visit[s]=1;//标记为入队
while(!q.empty())
{
int u=q.front();q.pop();//inqueue[u]++;
visit[u]=0; //标记出队
for(int i=head[u];i!=0;i=edge[i].next)//一个点一个点找
{
int v=edge[i].v,w=edge[i].w;//存下当前点的终点、权值
if(dis[v]>dis[u]+w)//判断直接到达权值小还是借助中间点到达权值小
{
dis[v]=dis[u]+w;//更新
if(visit[v]==0) //没有入队过
{
//先入队
visit[v]=1;
q.push(v);
inqueue[v]++;//当前点入队数量增加
if(inqueue[v]>n) return false; //当前点入队次数超过n,有负环
}
}
}
}
return true; //否则没有负环
}
int main()
{
scanf("%d%d%d",&n,&m,&s);//n点m边s起点
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w); //载入边
}
//输出
if(spfa() )//spfa判断是否有负环
{
cout<<"No negative circle"<<endl;
for(int i=1;i<=n;i++) cout<<dis[i]<<' ';
}
else cout<<"negative circle"<<endl;
return 0;
}
sfpa算法
最新推荐文章于 2024-04-13 13:54:08 发布