我好像不太擅长控制精度…
给出一些关系,判是否合法,于是考虑带权并查集
直接用分数表达要高精度(还要约分什么的不太可做),于是可以考虑分解质因数 但其实,只有乘除运算,我们可以考虑用对数 然后控一下精度
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; }