LightOJ - 1221 Travel Company(负环)

来源:互联网 发布:园林景观设计软件 编辑:程序博客网 时间:2024/05/19 22:24

题目大意:给你N个点,M条边,每条边有相应的 in和out,现在公司要求,找到一个环,使得这个环内的边的in / out > p

解题思路:将式子变形,环内的in / out > p,就变成了 0 > 环内的out * p - 环的in,就相当于找到一个负环了

#include <cstdio>#include <cstring>#include <queue>using namespace std;const int N = 110;const int M = 10010;struct Edge{    int v, dis, next;    Edge() {}    Edge(int v, int dis, int next): v(v), dis(dis), next(next) {} }E[M];int head[N], cnt[N], d[N];int n, m, p, cas = 1;bool vis[N];void solve() {    memset(d, 0, sizeof(d));    memset(cnt, 0, sizeof(cnt));    queue<int> Q;    for (int i = 0; i < n; i++) {        Q.push(i);        vis[i] = true;    }    while (!Q.empty()) {        int u = Q.front(); Q.pop();        vis[u] = false;        for (int i = head[u]; ~i; i = E[i].next) {            int v = E[i].v;            if (d[v] > d[u] + E[i].dis) {                d[v] = d[u] + E[i].dis;                if (!vis[v]) {                    vis[v] = true;                    Q.push(v);                    if (++cnt[v] >= n) {                        printf("Case %d: YES\n", cas++);                        return ;                    }                }            }        }    }    printf("Case %d: NO\n", cas++);}void init() {    scanf("%d%d%d", &n, &m, &p);    int u, v, in, out;    memset(head, -1, sizeof(head));    for (int i = 0; i < m; i++) {        scanf("%d%d%d%d", &u, &v, &in, &out);        int dis = out * p - in;        E[i] = Edge(v, dis, head[u]);        head[u] = i;    }}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0