http://www.lydsy.com/JudgeOnline/problemset.php
BZOJ的题都是中文的,但是这个鬼总是有人卡他们的服务器,然后评测就要等他们的服务器恢复正常。这点很气
这两道题目都是带权并查集的题目。
所谓的带权并查集,就是在并查集的基础上,加一个权值
两个代码差不是很多,主要的差别在于权值的不同。
1 //BZOJ 4602 2 3 4 #include <stdio.h> 5 #include <string.h> 6 #include <iostream> 7 #include <math.h> 8 const int maxn = 1e+5; 9 #define eps 1e-5 10 using namespace std; 11 12 double ans[ maxn ]; 13 int father[ maxn ]; 14 int m,n; 15 int a,b,c,d; 16 bool flag; 17 int Find(int x) 18 { 19 if(father[x]!=x) 20 { 21 int t = father[x]; 22 father[x] = Find(t); 23 ans[x] *= ans[t]; //这个是权值,每一个点相对于根节点的权值 24 } 25 return father[x]; 26 } 27 28 void unio(int a,int b) 29 { 30 int root1=Find(a),root2 = Find(b); 31 if(root1!=root2) 32 { 33 father[root2] = root1; 34 ans[root2]*=ans[a]/ans[b]*(double)d/c; //合并时,根节点的权值更新 35 36 }else { 37 if(fabs(ans[a]/ans[b]-1.0*c/d)>eps){ 38 flag = false; 39 } 40 } 41 } 42 43 void init() 44 { 45 for(int i = 1;i<=m;i++) 46 father[i] = i,ans[i] = 1; 47 } 48 49 50 int main() 51 { 52 int t; 53 while(cin>>t) 54 { 55 for(int Case = 1;Case<=t;Case++) 56 { 57 flag = true; 58 cin>>m>>n; 59 init(); 60 for(int i = 1;i<=n;i++) 61 { 62 cin>>a>>b>>c>>d; 63 unio(a,b); 64 } 65 if(flag) 66 cout<<"Case #"<<Case<<": Yes"<<endl; 67 else 68 cout<<"Case #"<<Case<<": No"<<endl; 69 70 } 71 } 72 return 0; 73 }
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <iostream> 5 const int maxn = 1e+5; 6 using namespace std; 7 8 int m,n; 9 int father[maxn]; 10 int ans[maxn]; 11 12 int Find(int x) 13 { 14 if(father[x]!=x) 15 { 16 int t = father[x]; 17 ans[x] += ans[t]; 18 father[x] = Find(t); 19 } 20 return father[x]; 21 } 22 23 void judge(int a,int b) 24 { 25 int root1 = Find(a); 26 int root2 =Find(b); 27 if(root1==root2) 28 printf("%d ",ans[a]-ans[b]); 29 else printf("UNKNOWN "); 30 } 31 32 33 34 void unio(int a,int b,int c) 35 { 36 int root1 = Find(a),root2 =Find(b); 37 if(root1!=root2) 38 { 39 father[root2]=root1; 40 ans[root2] =ans[a]-ans[b]-c; 41 } 42 } 43 44 int main() 45 { 46 int a,b,c; 47 char tmp; 48 while(scanf("%d%d",&n,&m),m||n) 49 { 50 for(int i = 1;i<=n;i++ ) 51 father[i] = i,ans[i] = 0; 52 for(int i = 1;i<=m;i++) 53 { 54 cin>>tmp; 55 getchar(); 56 if(tmp=='!') 57 { 58 cin>>a>>b>>c; 59 unio(a,b,c); 60 }else { 61 cin>>a>>b; 62 judge(a,b); 63 } 64 } 65 } 66 return 0; 67 }