【加权并查集】bzoj 4602 齿轮
立志用最少的代碼做最高效的表達
Description
現有一個傳動系統,包含了N個組合齒輪和M個鏈條。每一個鏈條連接了兩個組合齒輪u和v,并提供了一個傳動比x
: y。即如果只考慮這兩個組合齒輪,編號為u的齒輪轉動x圈,編號為v的齒輪會轉動y圈。傳動比為正表示若編號
為u的齒輪順時針轉動,則編號為v的齒輪也順時針轉動。傳動比為負表示若編號為u的齒輪順時針轉動,則編號為v
的齒輪會逆時針轉動。若不同鏈條的傳動比不相容,則有些齒輪無法轉動。我們希望知道,系統中的這N個組合齒
輪能否同時轉動。
Input
有多組數據,第一行給定整數T,表示總的數據組數,之后依次給出T組數據。每一組數據的第一行給定整數N和
M,表示齒輪總數和鏈條總數。之后有M行,依次描述了每一個鏈條,其中每一行給定四個整數u,v,x和y,表示
只考慮這一組聯動關系的情況下,編號為u的齒輪轉動x圈,編號為v的齒輪會轉動y圈。請注意,x為正整數,而y為
非零整數,但是y有可能為負數。
T<=32,N<=1000,M<=10000且x與y的絕對值均不超過100
Output
輸出T行,對應每一組數據。首先應該輸出標識這是第幾組數據,參見樣例輸出。之后輸出判定結果,如果N個組合
齒輪可以同時正常運行,則輸出Yes,否則輸出No。
Sample Input
2
3 3
1 2 3 5
2 3 5 -7
1 3 3 -7
3 3
1 2 3 5
2 3 5 -7
1 3 3 7
Sample Output
Case #1: Yes
Case #2: No
核心思路:帶權并查集模板
#include<bits/stdc++.h> #define N 1003 #define esp 1e-9 using namespace std; int n,m; int fa[N]; double sum[N]; int find(int x) { // 核心代碼if (fa[x]==x) return x;int t=find(fa[x]);sum[x]*=sum[fa[x]];fa[x]=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,sum[i]=1;bool pd=false;for (int i=1;i<=m;i++) {int u,v,x,y; scanf("%d%d%d%d",&u,&v,&x,&y);int r1=find(u); int r2=find(v);if (r1!=r2) {fa[r2]=r1;sum[r2]*=sum[u]/sum[v]*(double)y/x;}else if (fabs((double)(sum[u]/sum[v])-((double)x/(double)y))>esp) {pd=true;}}printf("Case #%d: ",t);printf(pd ? "No\n" : "Yes\n");}return 0; }總結
以上是生活随笔為你收集整理的【加权并查集】bzoj 4602 齿轮的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试官问我:如何解决ABA问题?我给出接
- 下一篇: 【已解决】Exception in th