【YBTOJ】【Luogu P3385】【模板】负环
链接:
题目大意:
判负环。
正文:
如果一个点被访问 \(n\) 次就说明有负环。
代码:
const int N = 2e3 + 10, M = 6e3 + 10;
inline ll Read()
{
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
struct edge
{
int to, val, nxt;
}e[M];
int head[N], tot;
void add(int u, int v, int w)
{
e[++tot] = (edge) {v, w, head[u]}, head[u] = tot;
return;
}
int t, n, m;
bool vis[N];
queue <int> q;
int dis[N], cnt[N];
bool SPFA()
{
memset (dis, 127 / 3, sizeof dis);
memset (cnt, 0, sizeof cnt);
memset (vis, 0, sizeof vis);
for (; !q.empty(); q.pop());
dis[1] = 0;
cnt[1] = vis[1] = 1;
q.push(1);
for (; !q.empty(); )
{
int u = q.front(); q.pop(); vis[u] = 0;
for (int i = head[u], v; i; i = e[i].nxt)
if (e[i].val + dis[u] < dis[v = e[i].to])
{
dis[v] = e[i].val + dis[u];
if (vis[v]) continue;
vis[v] = 1;
cnt[v] ++;
q.push(v);
if (cnt[v] >= n) return 1;
}
}
return 0;
}
int main()
{
for (t = Read(); t--; )
{
memset (head, 0, sizeof head);
tot = 0;
n = Read(), m = Read();
for (int i = 1; i <= m; i++)
{
int u = Read(), v = Read(), w = Read();
add(u, v, w);
if (w >= 0) add(v, u, w);
}
if (SPFA()) puts("YES");
else puts("NO");
}
return 0;
}