负环

Bellman-Ford

const int inf=0x3f3f3f3f,maxn=110,maxm=10010;
int n,m,dis[maxn];

struct Edge{
    int u,v,w;
}edge[maxm];

bool Bellman_Ford(){
    memset(dis,inf,sizeof(dis));
    dis[1]=0;
    for(int i=1;i<=n;i++){
        bool check=false;
        for(int j=1;j<=m;j++){
            int u=edge[j].u,v=edge[j].v,w=edge[j].w;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                check=true;
                if(i==n) return true;
            }
        }
        if(!check) break;
    }
    return false;
}

SPFA

const int maxn=1010,inf=0x3f3f3f3f;
int n,inq[maxn],cnt[maxn],dis[maxn];

bool spfa(int s){
    for(int i=1;i<=n;i++){
        dis[i]=(i==s)?0:inf;
        inq[i]=(i==s)?1:0;
        cnt[i]=(i==s)?1:0;
    }
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        int p=q.front();
        q.pop();
        inq[p]=0;
        for(int i=head[p];~i;i=nxt[i]){
            int v=to[i],w=weight[i];
            if(dis[v]>dis[p]+w){
                dis[v]=dis[p]+w;
                cnt[v]++;
                if(cnt[v]>=n) return true;
                if(!inq[v]){
                    inq[v]=1;
                    q.push(v);
                }
            }
        }
    }
    return false;
}

说明
1.如果判断是否存在从源点可达的负环,则在判断\(dis[v]\)\((dis[u]+w)\)的大小关系时,需要重新定义一个加法函数来模拟数学上关于无穷大的加减运算,变成判断\(dis[v]\)\(add(dis[u],w)\)的大小关系。

int add(int u,int v){
	if(u==inf || v==inf) return inf;
	return u+v;
}

2.正环
按照对应的方法计算最长路可以判断是否存在正环。

posted @ 2020-08-23 20:23  fxq1304  阅读(90)  评论(0编辑  收藏  举报