#include "iostream" #include "cstdio" #include "cstring" #include "queue" #include "algorithm" using namespace std; #define mem(a,y) memset(a,y,sizeof(a)) #define inf 0x7f7f7f7f const int maxn = 1100; const int maxm = 30000; struct node{ int v,len,next; }edge[maxm]; int head[maxn],dis[maxn],vis[maxn],Count[maxn]; int id,n; void add_edge(int u,int v,int len){ edge[id].v = v;edge[id].len = len;edge[id].next = head[u];head[u] = id++; } void init(int x,int y){ int u,v,len; memset(head,-1,sizeof(head));id = 0; while( x -- ){ //a[u] - a[v] < len scanf("%d %d %d",&u,&v,&len); add_edge(u,v,len); } while(y --){ //a[u] - a[v] > len scanf("%d %d %d",&v,&u,&len); add_edge(u,v,-len); } } int spfa(){ //当存在负环的时候,返回-1,当1到n没有路径时,返回-2,否则返回1到n最短距离 mem(dis,inf); mem(vis,0); mem(Count,0); dis[1] = 0;vis[1] = 1; queue<int>que; que.push(1); while( !que.empty()){ int u = que.front();que.pop();vis[u] = 0; for(int id = head[u]; id != -1; id = edge[id].next){ int v = edge[id].v; if( dis[v] - edge[id].len > dis[u]){ dis[v] = dis[u] + edge[id].len; if(!vis[v]){ if( ++Count[v] > n)return -1;//单一个点入队列超过n次,说明存在负环 vis[v] = 1;que.push(v); } } } } if( dis[n] == inf)dis[n] = -2; return dis[n]; } int main(){ int t,x,y; scanf("%d",&t); while( t-- ){ scanf("%d %d %d",&n,&x,&y); init(x,y); printf("%d ",spfa()); } return 0; }