P3371bellman_ford算法判负环+并查集优化

这题特殊情况在于,必须需要1能到达这个负环,而判断元素是否在同一集合,就需要用到并查集

#pragma optimize(2)
#include
#include
#include
#define endl '\n'
#define int int64_t
using namespace std;
const int N = 1e5 + 10;
struct edge { int v, w; };
vectore[N];
int d[N],m,n,fa[N],rec;
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
bool bellman_ford(int s) {
    memset(d, 0x3f3f3f3f, sizeof d);
    d[s] = 0;
    bool sign;
    for (int i = 1; i <= n; ++i) {//次数
        sign = false;
         for (int u = 1; u <= n; ++u) {//顶点
             if (d[u] == 0x3f3f3f3f)continue;
             for (auto k : e[u]) {
                 if (d[k.v] > d[u] + k.w) {
                       d[k.v] = d[u] + k.w;
                        rec = k.v;
                       sign = true;
                   }
             }
        }
         if (!sign) break;
    }
    return sign;
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t,a,b,c; cin >> t;
    while (t--) {
        for (int i = 1; i <= n; ++i) e[i].erase(e[i].begin(), e[i].end());
        cin >> n >> m;
        for (int i = 1; i <= n; ++i)fa[i] = i;
        for (int i = 1; i <= m; ++i) {
            cin >> a >> b >> c;
            e[a].push_back({ b,c });
            fa[find(a)] = find(b);
            if (c >= 0) e[b].push_back({ a,c });
        }
        if (bellman_ford(1)) {
            if(find(1) == find(rec))  cout << "YES" << endl;
            else cout << "NO" << endl;
        }
        else cout << "NO" << endl;
    }
    return 0;
}

你可能感兴趣的:(算法)