http://codeforces.com/gym/101243
题意:有三种药,是不同重量的三种药,但是不知道哪种是哪种,现在给你一些称量的结果,要你把这些药的种类区分出来
思路:最开始想的是并查集,但是一直没有想到怎么并,然后看了下别人的思路,就懂了。
当两个药的颜色一样的时候,并起来,然后颜色不同的时候,用一个两个数组分别记录一下,表示这两个药有差别,一个重,一个轻
然后之后分类,如果某个药既有比它重的,
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <vector> 5 using namespace std; 6 7 vector<pair<int,int> >v; 8 vector<int>s[1005]; 9 10 int father[1005]; 11 int down[1005],up[1005]; 12 char ans[1005]; 13 14 int Find(int x) 15 { 16 if(father[x]!=x) 17 return father[x] = Find(father[x]); 18 return father[x]; 19 } 20 21 22 void unio(int a,int b) 23 { 24 int root1 = Find(a); 25 int root2 = Find(b); 26 if(root1!=root2) 27 father[root1] = root2; 28 } 29 30 int main() 31 { 32 // freopen("input.txt","r",stdin); 33 // freopen("output.txt","w",stdout); 34 int m,n; 35 int a,b; 36 char c; 37 scanf("%d%d",&m,&n); 38 for(int i = 1;i<=m;i++) 39 { 40 father[i] = i; 41 ans[i]='?'; 42 } 43 for(int i = 0;i<n;i++) 44 { 45 scanf("%d%c%d",&a,&c,&b); 46 if(c=='=') 47 unio(a,b); 48 else { 49 if(c=='>') 50 swap(a,b); 51 v.push_back(make_pair(a,b)); 52 } 53 } 54 for(int i = 1;i<=m;i++) 55 { 56 Find(i); 57 s[Find(i)].push_back(i); 58 } 59 for(int i = 0;i<v.size();i++) 60 { 61 a = v[i].first; 62 b = v[i].second; 63 down[Find(a)]++; 64 up[Find(b)]++; 65 } 66 for(int i =1;i<=m;i++) 67 { 68 if(down[Find(i)]&&up[Find(i)]) 69 { 70 for(int j = 0;j<s[Find(i)].size();j++) 71 { 72 ans[s[Find(i)][j]] = 'R'; 73 } 74 s[Find(i)].clear(); 75 } 76 } 77 for(int i = 0;i<v.size();i++) 78 { 79 a = v[i].first; 80 b = v[i].second; 81 if(ans[a]=='R'){ 82 for(int j = 0;j<s[Find(b)].size();j++) 83 ans[s[Find(b)][j]] = 'W'; 84 s[Find(b)].clear(); 85 }else if(ans[b]=='R'){ 86 for(int j = 0;j<s[Find(a)].size();j++) 87 ans[s[Find(a)][j]]='B'; 88 s[Find(a)].clear(); 89 } 90 } 91 for(int i = 1;i<=m;i++) 92 printf("%c",ans[i]); 93 printf(" "); 94 return 0; 95 }
又有比他轻的那么说明这个一定是中间的药,那么所有的这个颜色的药都可以找出来
然后重的轻的都可以通过这个中间的药比较出来