题目大意
在一条数轴上你需要分配 个点的坐标,来满足 个条件。每个条件有三个参数 ,表示 的坐标比 小 。一个坐标上可以分配多个点。
询问你,存不存在一种分配方式,满足所有 个条件。
题解
考虑建图,对于每个条件,可以建立两条边, 表示 在 后 个坐标, 表示 在 后 个坐标。
遍历所有点跑 ,如果一个点没有被访问过,那么设置这个点在 上,然后 。 过程中,如果遇到没有访问过的点,就根据边设置点的坐标。如果遇到访问过的点,就 是否与边的要求冲突。
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define umap unordered_map
#define pq(x) priority_queue<x>
#define ppq(x) priority_queue<x,vector<x>,greater<x>>
#define endl '\n'
using namespace std;
using i128 = __int128;
const int mod =1e9+7;
template <typename T>void read(T&x){
x=0;int f = 1;
char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
x*=f;
}
template <typename T>void print(T x) {
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
#define int long long
const int N=2e5+5;
const int M=2e6+5;
int vis[N];
int poi[N];
vector<pair<int,int>> G[N];
int ans=1;
void dfs(int u)
{
vis[u]=1;
for(auto [v,w]:G[u])
{
if(vis[v])
{
if(poi[v]!=poi[u]+w) ans=0;
}
else
{
poi[v]=poi[u]+w;
dfs(v);
}
}
}
inline void solve()
{
int n,m;
cin>>n>>m;
ans=1;
for(int i=1;i<=n;i++) vis[i]=0,G[i].clear();
for(int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
G[u].push_back({v,w});
G[v].push_back({u,-w});
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
poi[i]=0;
dfs(i);
}
}
if(ans) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
signed main()
{
ios;
int T=1;
cin>>T;
for(;T--;) solve();
return 0;
}