题目大意:给你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;
}