• POJ


    http://poj.org/problem?id=3259

    看见500的数据量莽了一发Floyd,还T了。讲道理应该不至于的,换个快读试试。

    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<map>
    #include<set>
    #include<stack>
    #include<string>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    const int MAXN = 500;
    int dis[MAXN + 5][MAXN + 5];
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int t;
        scanf("%d", &t);
        while(t--) {
            memset(dis, 0x3f, sizeof(dis));
            int n, m, l;
            scanf("%d%d%d", &n, &m, &l);
            for(int i = 1; i <= n; ++i) {
                dis[i][i] = 0;
            }
            for(int i = 1; i <= m; ++i) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                dis[u][v] = min(dis[u][v], w);
                dis[v][u] = min(dis[v][u], w);
            }
            for(int i = 1; i <= l; ++i) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                dis[u][v] = min(dis[u][v], -w);
            }
            bool suc = 0;
            for(int k = 1; k <= n; ++k) {
                for(int i = 1; i <= n; ++i) {
                    for(int j = 1; j <= n; ++j) {
                        dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
                    }
                    if(dis[i][i] < 0) {
                        suc = 1;
                        break;
                    }
                }
                if(suc)
                    break;
            }
            puts(suc ? "YES" : "NO");
        }
    }
    

    但是假如图本身连通的话,写SPFA就可以了。

    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<map>
    #include<set>
    #include<stack>
    #include<string>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    const int MAXN = 505;
    const int MAXM = 10005;
    
    int top;
    int head[MAXN];
    struct Edge {
        int v, nxt;
        int w;
    } edge[MAXM];
    
    void init() {
        top = 0;
        memset(head, -1, sizeof(head));
    }
    
    void add_edge(int u, int v, int w) {
        ++top;
        edge[top].v = v;
        edge[top].w = w;
        edge[top].nxt = head[u];
        head[u] = top;
    }
    
    bool vis[MAXN];
    int cnt[MAXN];
    int dis[MAXN];
    
    queue<int>q;
    bool spfa(int s, int n) {
        memset(vis, 0, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
        for(int i = 0; i < MAXN; ++i)
            dis[i] = 0x3f3f3f3f;
    
        while(!q.empty())
            q.pop();
        q.push(s);
        vis[s] = 1;
        cnt[s] = 1;
        dis[s] = 0;
    
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for(int i = head[u]; i != -1; i = edge[i].nxt) {
                int v = edge[i].v;
                if(dis[v] > dis[u] + edge[i].w) {
                    dis[v] = dis[u] + edge[i].w;
                    if(!vis[v]) {
                        vis[v] = 1;
                        q.push(v);
                        if(++cnt[v] > n)
                            return 0;
                    }
                }
            }
        }
        return 1;
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int t;
        scanf("%d", &t);
        while(t--) {
            int n, m, l;
            scanf("%d%d%d", &n, &m, &l);
            init();
            for(int i = 1; i <= m; ++i) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                add_edge(u, v, w);
                add_edge(v, u, w);
            }
            for(int i = 1; i <= l; ++i) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                add_edge(u, v, -w);
            }
            bool suc = !spfa(1, n);
            puts(suc ? "YES" : "NO");
        }
    }
    

    速度172ms,可能可以试试优化。

    带SLF优化的SPFA,47ms,这么快是因为POJ抖了吗?

    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<map>
    #include<set>
    #include<stack>
    #include<string>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    const int MAXN = 505;
    const int MAXM = 10005;
    
    int top;
    int head[MAXN];
    struct Edge {
        int v, nxt;
        int w;
    } edge[MAXM];
    
    void init() {
        top = 0;
        memset(head, -1, sizeof(head));
    }
    
    void add_edge(int u, int v, int w) {
        ++top;
        edge[top].v = v;
        edge[top].w = w;
        edge[top].nxt = head[u];
        head[u] = top;
    }
    
    bool vis[MAXN];
    int cnt[MAXN];
    int dis[MAXN];
    
    deque<int>q;
    bool spfa(int s, int n) {
        memset(vis, 0, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
        for(int i = 0; i < MAXN; ++i)
            dis[i] = 0x3f3f3f3f;
    
        q.clear();
        q.push_back(s);
        vis[s] = 1;
        cnt[s] = 1;
        dis[s] = 0;
    
        while(!q.empty()) {
            int u = q.front();
            q.pop_front();
            vis[u] = 0;
            for(int i = head[u]; i != -1; i = edge[i].nxt) {
                int v = edge[i].v;
                if(dis[v] > dis[u] + edge[i].w) {
                    dis[v] = dis[u] + edge[i].w;
                    if(!vis[v]) {
                        vis[v] = 1;
                        //SLF优化 据说15%~20%
                        if(!q.empty() && dis[v] >= dis[q.front()])
                            q.push_back(v);
                        else
                            q.push_front(v);
                        if(++cnt[v] > n)
                            return 0;
                    }
                }
            }
        }
        return 1;
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int t;
        scanf("%d", &t);
        while(t--) {
            int n, m, l;
            scanf("%d%d%d", &n, &m, &l);
            init();
            for(int i = 1; i <= m; ++i) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                add_edge(u, v, w);
                add_edge(v, u, w);
            }
            for(int i = 1; i <= l; ++i) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                add_edge(u, v, -w);
            }
            bool suc = !spfa(1, n);
            puts(suc ? "YES" : "NO");
        }
    }
    
  • 相关阅读:
    2020牛客暑期多校训练营(第三场)
    2020牛客暑期多校训练营(第二场)
    C# 获取枚举类型中所有描述信息 Xinner
    XPath Xinner
    02kubeadm安装
    thinkphp6:访问redis6(thinkphp 6.0.9/php 8.0.14)
    npm8.3.0 安装@vue/cli 4.5.15
    linux(ubuntu 21.10): php8.0.14:安装phpredis以访问redis(phpredis5.3.5)
    linux(ubuntu21.10):apt方式安装redis6.0.15
    阿里云何万青:南坡VS北坡,阿里云高性能计算行业实践
  • 原文地址:https://www.cnblogs.com/Inko/p/11728777.html
Copyright © 2020-2023  润新知