#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <stack> #include <queue> #include <vector> #include <set> #include <map> #include <stdlib.h> #define ri register int struct Node { int to,val,next; }edge[6005]; int head[2005],cnt=1; bool vis[2005]; int in[2005];//记录一个点被更新多少次 int dis[2005]; int n,m; std::queue<int>q; void add(int u,int v,int w)//链表存图 { edge[cnt].to=v; edge[cnt].next=head[u]; edge[cnt].val=w; head[u]=cnt; cnt++; } bool spfa() { q.push(1); vis[1]=true; in[1]++; dis[1]=0; while(q.size()) { int p=q.front();//取出队首元素 vis[p]=false; q.pop(); for(ri i=head[p];i;i=edge[i].next) //极其板子的SPFA { int v=edge[i].to; if(dis[v]>edge[i].val+dis[p]) { dis[v]=edge[i].val+dis[p]; in[v]++;//更新次数++ if(in[v]>=n)return true;//如果一个点被更新超过N次,那么存在负环 if(!vis[v]) { vis[v]=true; q.push(v); } } } } return false;//如果不存在负环,返回false; } int main() { int t; scanf("%d",&t);//t组数据 for(ri i=1;i<=t;i++) { std::memset(head,0,sizeof(head)); std::memset(edge,0,sizeof(edge)); std::memset(vis,0,sizeof(vis)); std::memset(in,0,sizeof(in)); std::memset(dis,0x3f,sizeof(dis)); //初始化 cnt=1; scanf("%d%d",&n,&m); for(ri i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); if(w>=0)add(v,u,w);//简单的存图操作 } if(spfa())printf("YES "); else printf("NO "); } return 0; }