#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
struct Edge {
int to, weight;
};
vector<Edge> graph[MAXN];
int in_degree[MAXN];
bool visited[MAXN];
vector<int> cycle_weights;
void dfs(int u, vector<int>& path, vector<bool>& in_path) {
visited[u] = true;
in_path[u] = true;
path.push_back(u);
for (const Edge& e : graph[u]) {
if (in_path[e.to]) {
int start = find(path.begin(), path.end(), e.to) - path.begin();
for (int i = start; i < path.size() - 1; ++i) {
for (const Edge& edge : graph[path[i]]) {
if (edge.to == path[i + 1]) {
cycle_weights.push_back(edge.weight);
break;
}
}
}
cycle_weights.push_back(e.weight);
} else if (!visited[e.to]) {
dfs(e.to, path, in_path);
}
}
path.pop_back();
in_path[u] = false;
}
bool topological_sort(int n) {
queue<int> q;
for (int i = 1; i <= n; ++i) {
if (in_degree[i] == 0) {
q.push(i);
}
}
int count = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
++count;
for (const Edge& e : graph[u]) {
if (--in_degree[e.to] == 0) {
q.push(e.to);
}
}
}
return count != n;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
vector<int> ans(T, 0);
for(int p = 0; p < T; p++) {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
graph[i].clear();
in_degree[i] = 0;
visited[i] = false;
}
cycle_weights.clear();
for (int i = 0; i < m; ++i) {
int u, v, w;
cin >> u >> v >> w;
graph[u].push_back({v, w});
++in_degree[v];
}
if (topological_sort(n)) {
vector<int> path;
vector<bool> in_path(n + 1, false);
for (int i = 1; i <= n; ++i) {
if (!visited[i]) {
dfs(i, path, in_path);
}
}
int sum = 0;
for (int weight : cycle_weights) {
sum += weight;
}
ans[p] = sum;
}
}
for(int i = 0; i < T; i++) {
cout << (ans[i] < 0 ? "YES" : "NO") << endl;
}
return 0;
}
众所周知,拓扑排序可以找到有向图中的环,所有我用拓扑排序找到了环,再判断环上所有边权加起来的和是否小于0,然后得了个0分,有没有大佬帮一下(SPFA已过)