SPFA判断负环

哇这道题我真的是被机惨了。。。

 

 太真实了。。

#include<bits/stdc++.h>
#define R register int
using namespace std;
const int N=2005,inf=0x3f3f3f3f,M=10005;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9') if(ch=='-') f=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
int head[N],Next[M],val[M],go[M],dis[N];
int tot,n,m,cnt[N];
bool book[N];
inline void add(int x,int y,int z)
{
    Next[++tot]=head[x];
    val[tot]=z;
    go[tot]=y;
    head[x]=tot;
}
inline bool SPFA()
{
    //memset(cnt,1,sizeof(cnt));
    memset(dis,0x3f,sizeof(dis));
    //memset(book,1,sizeof(book));
    queue<int> Q;
    for(R i=1;i<=n;i++)
    {
        book[i]=1;
        Q.push(i);
    }//因为本质上并不是要求最短路,而是判断负环,所以事实上要先将所有的点都入队。 
    dis[1]=0;
    //book[1]=true;
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();book[u]=0;
        for(R i=head[u];i;i=Next[i])
        {
            int v=go[i];
            //if(book[v]) continue;
            if(dis[v]>dis[u]+val[i])
            {
                dis[v]=dis[u]+val[i];
                cnt[v]=cnt[u]+1;//一个点的经过次数超过n,说明有负环。 
                if(cnt[v]>=n) return true;
                if(!book[v]) book[v]=1,Q.push(v);
            }
        }
    }
    return false;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(R i=1;i<=m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }
    if(SPFA()) cout<<"Yes";
    else cout<<"No";
    return 0;
}

注释都在代码里了

posted @ 2019-11-06 15:30  Gold_stein  阅读(480)  评论(0编辑  收藏  举报