判断是否存在环模板(拓扑排序,Bellman_ford算法)

(一)Bellman_ford:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,b) for(int a=0;a<b;a++)
using namespace std;
const int maxn =  1e4;
const int INF = 0x3f3f3f3f;
const int inf = 0x3f;

int dis[maxn];
struct edge{
    int s,e;    ///起点,终点
    int w;      ///权值
}e[maxn];
int n,m;                //n为点,m为边的总数
bool bellman(int a,int n)     ///求a->其他点的最短路,n为结点总数.可判负环
{
    memset(dis,inf,(n+1)<<2);          
    dis[a]=0;
    For(i,n-1)
        For(j,m)
            dis[e[j].e]=min(dis[e[j].e],dis[e[j].s]+e[j].w);    ///松弛操作
    For(i,m)                                                    ///松弛完后还能再松弛即代表有负环
        if(dis[e[i].e]>dis[e[i].s]+e[i].w)
            return true;
    return false;
}
int main()
{
    cin>>n>>m;
    For(i,m)
        cin>>e[i].s>>e[i].e>>e[i].w;

    if(bellman(1,n))
        cout << "有负环" << endl;
    else
        for(int i=1;i<=n;i++){
        if(dis[i]!=INF)
            cout<< dis[i] << endl;
        else
           cout <<"INF" << endl;
    }
}

(二)拓扑排序:只在有向无环图中成立

https://blog.csdn.net/u012860063/article/details/41170183

//拓扑排序判断是否存在环
#include<iostream>
#define maxn 510
using namespace std;
int G[maxn][maxn];      //记录路径
int in_degree[maxn];    //记录入度
int ans[maxn];
int n,m,x,y;
int i,j;
int flag=0;

void toposort(){
    flag=0;
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            if(G[i][j])
                in_degree[j]++;
        }
    }

    for(i=1;i<=n;i++){  //从最小的开始找
        //这样保证有多个答案时候序号小的先输出
        int k=1;
        while(!in_degree[k]){   //寻找入度为0的点
            k++;
            if(k>n){
                flag=1;
                break;
            }
        }

        ans[i]=k;
        in_degree[k]=-1;
        //更新为-1,后面检测补受影响,相当于删除结点
        for(int j=1;j<=n;j++){
            if(G[k][j]){
                in_degree[j]--;  //相连的入度减1
            }
        }
    }
}

int main(){
    while(cin>>n){
        memset(in_degree,0,sizeof(in_degree));
        memset(ans,0,sizeof(ans));
        memset(G,0,sizeof(G));

        for(i=1;i<=n;i++){
            cin>>m;
            for(j=0;j<m;j++){
                cin>>y;
                G[i][y]=1;
            }
        }

        toposort();
        if(flag)
            cout<<"0"<<endl;
        else
            cout<<"1"<<endl;
    }
    return 0;
}
    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/qq_37360631/article/details/81292377
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞