• [luogu] P3385 【模板】负环


    题目描述

    暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索

    输入输出格式

    输入格式:

    第一行一个正整数T表示数据组数,对于每组数据:

    第一行两个正整数N M,表示图有N个顶点,M条边

    接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向)

    输出格式:

    共T行。对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输出一行"N0"(不含引号)。

    输入输出样例

    输入样例#1: 
    2
    3 4
    1 2 2
    1 3 4
    2 3 1
    3 1 -3
    3 3
    1 2 3
    2 3 4
    3 1 -8
    
    输出样例#1:
    N0
    YE5
    

    说明

    nleq 2000n2000mleq 3000m3000-10000leq wleq 1000010000w10000Tleq 10T10

    建议复制输出格式中的字符串。

    code

    //T到MMP...实测INF不设成10000绝对T
    //深吸一口氧
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    const int INF = 10000;
    const int MAXN = 30000;
    int T, n, m;
    int head[MAXN * 2], tot = 0;
    int dis[MAXN], cnt[MAXN];
    bool vis[MAXN];
    
    struct Edge {
        int node, next, value;
    }e[MAXN];
    
    inline int read() {
        int num = 0, f = 1; char ch = getchar();
        while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
        while (isdigit(ch)) { num = num * 10 + ch - '0'; ch = getchar(); }
        return num * f;
    }
    
    void Add_Edge(int x, int y, int w) {
        e[++tot].node = y; e[tot].value = w; e[tot].next = head[x]; head[x] = tot;
    } 
    
    bool SPFA(int s) {
        queue<int> q;
        memset(dis, INF, sizeof(dis));
        memset(vis, false, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
        dis[s] = 0;
        vis[s] = true;
        cnt[s] = 1;
        q.push(s);
        while (!q.empty()) {
            int h = q.front();
            q.pop();
            vis[h] = false;
            for (int i = head[h], v; ~i, v = e[i].node; i = e[i].next) {
                if (dis[h] + e[i].value < dis[v]) {
                    if (++ cnt[v] >= n) return true;
                    dis[v] = dis[h] + e[i].value;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = true;
                    }
                }
            } 
        }
        return false;
    }
    
    int main() { 
        T = read();
        while (T --) {
            tot = 0;
            memset(head, -1, sizeof(head));
            n = read(); m = read();
            for (int i = 1; i <= m; ++ i) {
                int x = read(), y = read(), w = read();
                Add_Edge(x, y, w);
                if (w >= 0) Add_Edge(y, x, w);
            }
            if(SPFA(1)) printf("YE5
    ");
            else printf("N0
    ");
        }
        return 0;
    } 
  • 相关阅读:
    Dom之标签增删操作
    Dom实例:数据自增、搜索框及跑马灯
    Dom选择器及操作文本内容
    Tkinter单选框及滚动条
    Tkinter颜色方案举例
    TKinter之窗口美化 窗口大小、图标等
    TKinter之文本域与多窗口
    TKinter之菜单
    JavaScript 基本语法
    TKinter的常用组件
  • 原文地址:https://www.cnblogs.com/hkttg/p/9078071.html
Copyright © 2020-2023  润新知