→题目链接←
【想说的话】
依旧没有什么想说的...
【题解】
对于每个三元组(x,y,z)
点x向点n+y连接一个权值为z的边
点n+y向x点连接一个权值为-z的边
然后跑dfs
当找到一个访问过的点,并且到这个点的距离与之前记录的距离不一样,那么就一定不合法
【代码】
#include<bits/stdc++.h>
#define mod 1000000007
#define MAXN 2020
typedef long long ll;
using namespace std;
inline int rd(){
int x=0,y=1;char c=getchar();
while(c<'0' || c>'9'){if(c=='-')y=-y;c=getchar();}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x*y;
}
struct node{
int to,len;
node(int x,int y){to=x,len=y;}
};
int T,n,m,k;
bool vis[MAXN],flag;
int dis[MAXN];
vector<node>v[MAXN];
void pre(){
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
for(int i=1; i<=n+m; i++)v[i].clear();
}
void dfs(int x){
vis[x]=1;
for(int i=0; i<v[x].size(); i++){
int to=v[x][i].to;
int len=v[x][i].len;
if(!vis[to]){
dis[to]=dis[x]+len;
dfs(to);
}
else if(vis[to] && dis[to]!=dis[x]+len)flag=false;
}
}
void work(){
flag=true;
n=rd(),m=rd(),k=rd();
pre();
for(int i=0; i<k; i++){
int x=rd(),y=rd(),z=rd();
v[x].push_back(node(n+y,z));
v[n+y].push_back(node(x,-z));
}
for(int i=1; i<=n+m; i++)if(!vis[i])dfs(i);
if(!flag)puts("No");
else puts("Yes");
}
int main(){
T=rd();
while(T--)work();
return 0;
}