我好像不太擅长控制精度…
给出一些关系,判是否合法,于是考虑带权并查集
直接用分数表达要高精度(还要约分什么的不太可做),于是可以考虑分解质因数
但其实,只有乘除运算,我们可以考虑用对数
然后控一下精度
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 11000;
const double eps = 1e-8;
int n,m;
int fa[maxn];
double f[maxn];
int sig[maxn];
int find_(const int x)
{
if(fa[x]==x) return x;
int t=fa[x]; fa[x]=find_(t);
f[x]+=f[t];
sig[x]*=sig[t];
return fa[x];
}
int main()
{
int t; scanf("%d",&t);
for(int T=1;T<=t;T++)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) fa[i]=i,f[i]=0,sig[i]=1;
bool flag=true;
while(m--)
{
int u,v,x,y,s=1; scanf("%d%d%d%d",&u,&v,&x,&y);
if(y<0) s=-1,y=-y;
double c=log((double)y/(double)x);
int t1=find_(u),t2=find_(v);
if(t1!=t2)
{
s*=sig[v];
c=c-f[v];
fa[t2]=u,f[t2]=c,sig[t2]=s;
}
else
{
int s2=sig[v]*sig[u];
double c2=f[v]-f[u];
if(s2!=s||fabs(c2-c)>eps) flag=false;
}
}
printf("Case #%d: ",T);
if(flag) puts("Yes");
else puts("No");
}
return 0;
}