社区讨论

SPFA没有死!

P3385【模板】负环参与者 12已保存回复 14

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
14 条
当前快照
1 份
快照标识符
@mi7z1sza
此快照首次捕获于
2025/11/21 05:57
4 个月前
此快照最后确认于
2025/11/21 06:47
4 个月前
查看原帖
CPP
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

int head[2050],size,n,m;
int f;
int t;
int vis[2050],dis[2050];
int looker[2050];

struct edge{
    int next,to,dis;
};
edge e[10086];

void addedge(int next,int to,int dis)
{
    e[++size].to=to;
    e[size].dis=dis;
    e[size].next=head[next];
    head[next]=size;
}

void spfa(int start)
{
    queue <int> q;
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(looker,0,sizeof(looker));
    q.push(start);
    vis[start]=1;
    dis[start]=0;
    looker[start]=1; 
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        vis[t]=0;
        int i,j,k;
        for(i=head[t];i;i=e[i].next)
        {
            j=e[i].to;
            k=e[i].dis;
            if(dis[t]+k<dis[j])
            {
            	dis[j]=dis[t]+k; 
                if(vis[j]) continue;
                vis[j]=1;
                looker[j]++;
                if(looker[j]>n) 
                {
                    f=0;
                    return ;
                }
                q.push(j);
            }
        }
    }
}
int main()
{
    int i,j;
    int k;
    scanf("%d",&t);
    for(k=1;k<=t;k++)
    {
        memset(head,0,sizeof(head));
        size=0;
        f=1;
        scanf("%d %d",&n,&m);
        for(j=1;j<=m;j++)
        {
            int t1,t2,t3;
            scanf("%d %d %d",&t1,&t2,&t3);
            if(t3>=0)
            {
                addedge(t1,t2,t3);
                addedge(t2,t1,t3);
            }
            if(t3<0)
            {
                addedge(t1,t2,t3);
            }
        }
        spfa(1);
        if(!f) printf("YE5\n");
        else printf("N0\n");
    }
    return 0;
}
原理:如果有没有负环的话SPFA每个点必然刷新n次以下(见bellman-ford)。

回复

14 条回复,欢迎继续交流。

正在加载回复...