• POJ 3259 Wormholes 最短路+负环


    原题链接:http://poj.org/problem?id=3259

    题意

    有个很厉害的农民,它可以穿越虫洞去他的农场,当然他也可以通过道路,虫洞都是单向的,道路都是双向的,道路会花时间,虫洞会倒退时间,问你这个农民可不可以回到起点,并且在他出发的时间之前。

    题解

    就虫洞用负边链接,然后判断是否有负环即可。

    代码

    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<string>
    #include<algorithm>
    #include<queue>
    #define INF 2500003
    #define MAX_N 555
    using namespace std;
    
    struct edge {
    public:
        int to, cost;
    
        edge(int t, int c) : to(t), cost(c) { }
    
        edge() { }
    };
    
    vector<edge> G[MAX_N];
    int d[MAX_N];
    queue<int> que;
    bool inQue[MAX_N];
    bool vis[MAX_N];
    int n,m,w;
    int cnt[MAX_N];
    
    void init(){
        for(int i=0;i<=n;i++)G[i].clear();
        fill(d,d+n+1,INF);
        memset(vis,0,sizeof(vis));
        while(que.size())que.pop();
        memset(inQue,0,sizeof(inQue));
        memset(cnt,0,sizeof(cnt));
    }
    
    bool spfa(int s) {
        que.push(s);
        inQue[s] = 1;
        vis[s] = 1;
        d[s] = 0;
        cnt[s] = 1;
        while (que.size()) {
            int u = que.front();
            que.pop();
            inQue[u] = 0;
            for (int i = 0; i < G[u].size(); i++) {
                int v = G[u][i].to;
                int c = G[u][i].cost;
                if (d[u] + c < d[v]) {
                    d[v] = d[u] + c;
                    if (!inQue[v]) {
                        inQue[v] = 1;
                        que.push(v);
                        cnt[v]++;
                        if (cnt[v] > n)return true;
                    }
                }
            }
        }
        return false;
    }
    
    int T;
    
    int main() {
        cin.sync_with_stdio(false);
        cin >> T;
        while (T--) {
            cin >> n >> m >> w;
            init();
            for (int i = 0; i < m; i++) {
                int u, v, c;
                cin >> u >> v >> c;
                G[u].push_back(edge(v, c));
                G[v].push_back(edge(u, c));
            }
            for (int i = 0; i < w; i++) {
                int u, v, c;
                cin >> u >> v >> c;
                G[u].push_back(edge(v, -c));
            }
            bool flag = false;
            for (int i = 0; i < n; i++)
                if (!vis[i]) {
                    flag = spfa(i);
                    if (flag)
                        break;
                }
            if (flag)cout << "YES" << endl;
            else cout << "NO" << endl;
        }
        return 0;
    }
  • 相关阅读:
    经济--1...19
    经济
    金融--
    经济--番外篇
    经济--基金问答
    经济--如何买基金?
    PHP面向对象常见的关键字和魔术方法
    php对象中类的继承性访问类型控制
    详解PHP的__set()、__get()、__isset()、unset()四个方法
    子类重载父类的方法“parent:方法名”
  • 原文地址:https://www.cnblogs.com/HarryGuo2012/p/4756309.html
Copyright © 2020-2023  润新知