本题大意:在农场中存在时空虫洞,可以让人回到以前的多少秒前,问是否存在某个点,通过虫洞和其他路径能够在当前时间或以前回到现在的起点。
本题大意可以看出,这是一个判断图中是否存在环的题,一般情况下,用dfs来找环比较方便,所以将图建好后,把每个点都遍历一边,判断时候能回到起点就行了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <cmath>
#define inf 0x3f3f3f3f
#define init(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
using namespace std;
typedef long long ll;
int n,m1,t,m2,q,w,e,vis[1005],flag,dis[1005];
struct sa
{
int to,cost;
};
vector<sa>a[1005];
void spfa(int x)
{
vis[x]=1;
for(int i=0; i<a[x].size(); i++)
{
if(dis[a[x][i].to]>dis[x]+a[x][i].cost)
{
dis[a[x][i].to]=dis[x]+a[x][i].cost;
if(vis[a[x][i].to])
{
flag=1;
return;
}//如果这个点被访问过,那么就存在环
spfa(a[x][i].to);
}
}
vis[x]=0;
}
int main()
{
init();
cin>>t;
while(t--)
{
cin>>n>>m1>>m2;
for(int i=1;i<=m1;i++)
{
cin>>q>>w>>e;
a[q].push_back({w,e});
a[w].push_back({q,e});
}
for(int i=1;i<=m2;i++)
{
cin>>q>>w>>e;
a[q].push_back({w,-e});
}//标准建图
flag=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
memset(dis,0,sizeof(dis));
spfa(i);
if(flag)break;
}
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
for(int i=1;i<=n;i++)a[i].clear();
}
return 0;
}