zoukankan      html  css  js  c++  java
  • SPFA判断负环

    例题

    https://www.luogu.org/problemnew/show/P3385

    说明一下,这个例题用下面的方法是过不了的,只能过掉25分因为数据加强了,而我不会写BFS版SPFA判负环

    但是我觉得会DFS版的就行了,反正对于随机数据DFS版的绝对吊打BFS版的

    只不过这道题的数据不是随机的,是有人恶意添加的


    坑点

    • hint中已经提到的建议粘贴输出的字符串,因为是YE‘5’,而不是‘S’,是N‘0’,而不是O(统统毒瘤
    • 图不一定是联通的,是不是很强,这更让我们感受到了世界的敌意
    • 如果要判负环的话,对于最短路的部分,我们就可以舍弃掉一部分了,dis=0额不是dis=INF因为这样可以最大程度的优化程序,将最短路的求解部分弱化

    思路

    我们利用DFS强行进行松弛操作(我感觉已经不能叫他SPFA了)

    如果在一条路径上一个点被重复访问过了,那就是说明出现了负环

    输出YE5就行了

    代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    const int maxnode = 2007;
    const int maxedge = 3007*2;
    
    using namespace std;
    
    int x, f;
    char c;
    
    inline int read() {
        x = 0, f = 1;
        c = getchar();
        while (c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while (c >= '0' && c <= '9') {
            x = x*10 + c-'0';
            c = getchar();
        }
        return x * f;
    }
    
    int T, n, m, u[maxedge], v[maxedge], w[maxedge];
    int first[maxnode], nur[maxedge], dis[maxnode];
    bool vis[maxnode], book;
    
    inline void addedge(int f, int i) {
        nur[i] = first[f]; first[f] = i;
    }
    
    int k;
    
    inline void SPFA(int s) {
        if(book) return ;
        vis[s] = 1;
        k = first[s];
        while (k != -1) {
            if(book) return ;
            if(dis[v[k]] > dis[u[k]] + w[k]) {
                dis[v[k]] = dis[u[k]] + w[k];
                if(vis[v[k]]) book = 1;
                else SPFA(v[k]);
            }
            k = nur[k];
        }
        vis[s] = 0;
    }
    
    int main() {
        T = read();
        while (T--) {
            n = read(), m = read();
            book = 0;
            memset(first, -1, sizeof(first));
            memset(vis, 0, sizeof(vis));
            memset(dis, 0, sizeof(dis));
            memset(nur, -1, sizeof(nur));
            for(int i=1; i<=m*2; i++) {
                u[i] = v[i+1] = read(); v[i] = u[i+1] = read(); w[i] = w[i+1] = read();
                addedge(u[i], i);
                i++;
                if(w[i] >= 0) {
                    addedge(u[i], i);
                }
            }
            for(int i=1; i<=n&&!book; i++)
                SPFA(i);
            (book)?(puts("YE5")):(puts("N0"));
        }
        return 0;
    }
  • 相关阅读:
    彻底弄懂flex布局
    剖析Vue原理&实现双向绑定MVVM
    【Mysql进阶-3】大量实例悟透EXPLAIN与慢查询
    mysql 排序
    从ReentrantLock的实现看AQS的原理及应用
    Java面试之Synchronized解析
    基于vue-cli搭建vue项目开发环境
    在win环境下使用yarn安装 vue-cli
    优化器追踪示例
    MySQL常见的七种锁详细介绍
  • 原文地址:https://www.cnblogs.com/bljfy/p/9269620.html
Copyright © 2011-2022 走看看