SPFA判负环(模板)

版权声明:copy right https://blog.csdn.net/qq_43521140/article/details/89678154

洛谷P3385

SPFA判负环

 //7777777
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<math.h>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<utility>
    #include<vector>
    #define lson l , m , rt << 1
    #define rson m+1 , r , rt << 1 | 1
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    const double pi = 3.1415926535;
    const double eps = 1e-6;
    const int MXN = 1e5 + 7;
    const int MXM = 1e6 + 7;
    const int MX = 1e4 + 7;
    const int maxbit = 18;
    const double val = pi/180.0;
    const int INF = 0x3f3f3f3f;
    const ll LINF = 0x3f3f3f3f3f3f3f3f;
    struct Edge
    {
        int to,w,next;
    }e[MX << 1];
    int cnt,n,m;
    int head[MX];
    inline void add(int u,int v,int w)
    {
        e[++cnt].to = v;
        e[cnt].w = w;
        e[cnt].next = head[u];
        head[u] = cnt;
    }
    bool SPFA(int S)
    {
        int num[MX] = {0};
        int vis[MX] = {0};
        int d[MX];
        queue<int>q;
        mem(vis,0);
        for(int i = 1;i <= n;++i) d[i] = INF;
        d[S] = 0;
        vis[S] = 1;
        q.push(S);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for(int i = head[u];i;i=e[i].next)
            {
                int v = e[i].to;
                int w = e[i].w;
                if(d[v] > d[u] + w){
                    d[v] = d[u] + w;
                    if(!vis[v])
                    {
                        q.push(v);
                        vis[v] = 1;
                        num[v]++;
                    }
                    if(num[v] > n) return true;//存在负环
                }
            }
        }
        return false;//不存在负环
    }
    void init()
    {
        mem(head,0);
        mem(e,0);
        cnt = 0;
    }
    int main()
    {
        int T;
        cin >> T;
        while(T--)
        {
            init();
            cin >> n >> m;
            while(m--)
            {
                int u,v,w;
                cin >> u >> v >> w;
                add(u,v,w);
                //此题中要求 若出现负边则为单向边
                if(w >= 0) add(v,u,w);
            }
            if(SPFA(1)) cout << "YE5" << endl;
            else cout << "N0" << endl;
        }
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/qq_43521140/article/details/89678154
今日推荐