[TC2016BeijingDiv1] DarkMatterParticles(并查集,01背包)
Problem Statement Maya has n volatiel dark matter particles in her research facility (particles are numbered as 0, 1, 2, ..., n-1). They are all kept in one giant jar as some particles, if separated far away, would explode. Maya recently received a huge research grant, and built a new research facility on another planet. Maya wishes to transport exactly k of the particles to the new facility for further experiments. Maya needs to figure out which k particles she can safely transport to the new facility so that no particle would explode. Maya has a list of pairs described by x and y such that if the two particles x[i] and y[i] are separated, they would explode (assume x[i] is not equal to y[i] for all i). In particular, if Maya transports only one of x[i] and y[i] to the new facility (thereby the other one remaining in the current facility), they would explode. Therefore Maya needs to keep both particles x[i] and y[i] in her current facility or to transport both particles to the new facility (for every i). Given this information, please help Maya by determining whether it is possible to transport exactly k particles to the new facility without resulting in any explosion. If it is possible, return "Possible"; otherwise return "Impossible" (all quotes for clarity). Definition Class: DarkMatterParticles Method: SplitParticles Parameters: int, int, vector <int>, vector <int> Returns: string Method signature: string SplitParticles(int n, int k, vector <int> x, vector <int> y) (be sure your method is public) Limits Time limit (s): 2.000 Memory limit (MB): 256 Constraints - n will be between 2 and 1,000, inclusive. - k will be between 1 and 1,000, inclusive. - x will contain between 1 and 2,500 elements, inclusive. - x and y will contain the same number of elements. - Each element in x will be between 0 and n-1, inclusive. - Each element in y will be between 0 and n-1, inclusive. - For each valid i, x[i] != y[i]. Examples 0) 4 2 {0,1,2,3} {1,2,3,0} Returns: "Impossible" 1) 4 4 {0,1,2,3} {1,2,3,0} Returns: "Possible" 2) 4 2 {0,1,2,3} {2,3,0,1} Returns: "Possible" 3) 4 3 {0,1,2,3} {2,3,0,1} Returns: "Impossible" 4) 3 3 {0,1,2} {1,2,0} Returns: "Possible" 5) 3 2 {0,1,2} {1,2,0} Returns: "Impossible" 6) 6 1 {0,1,4} {1,2,5} Returns: "Possible" 7) 6 2 {0,1,4} {1,2,5} Returns: "Possible" 8) 6 3 {0,1,4} {1,2,5} Returns: "Possible" 9) 6 6 {0,1,4} {1,2,5} Returns: "Possible"
一共有n个点,有一些点必须一起被装在背包里,现在给了好多点,问背包能不能装恰好k个点。
用并查集维护各个堆,然后每一堆做一个物品的重量,做01背包即可。
1 // BEGIN CUT HERE 2 3 // END CUT HERE 4 #line 5 "DarkMatterParticles.cpp" 5 #include <cstdlib> 6 #include <cctype> 7 #include <cstring> 8 #include <cstdio> 9 #include <cmath> 10 #include <algorithm> 11 #include <vector> 12 #include <string> 13 #include <iostream> 14 #include <sstream> 15 #include <map> 16 #include <set> 17 #include <queue> 18 #include <stack> 19 #include <fstream> 20 #include <numeric> 21 #include <iomanip> 22 #include <bitset> 23 #include <list> 24 #include <stdexcept> 25 #include <functional> 26 #include <utility> 27 #include <ctime> 28 using namespace std; 29 30 const int maxn = 1010; 31 int pre[maxn], sz[maxn], dp[maxn]; 32 vector<int> v; 33 int find(int x) { return x == pre[x] ? x : pre[x] = find(pre[x]); } 34 void unite(int x, int y) { pre[find(x)] = find(y); } 35 class DarkMatterParticles 36 { 37 public: 38 string SplitParticles(int n, int k, vector <int> x, vector <int> y) 39 { 40 if(n == k) return "Possible"; 41 if(n < k) return "Impossible"; 42 for(int i = 0; i < maxn; i++) pre[i] = i; 43 memset(sz, 0, sizeof(sz)); 44 memset(dp, 0, sizeof(dp)); 45 dp[0] = 1; v.clear(); 46 for(int i = 0; i < x.size(); i++) unite(x[i], y[i]); 47 for(int i = 0; i < n; i++) sz[find(i)]++; 48 for(int i = 0; i < n; i++) if(sz[i]) v.push_back(sz[i]); 49 for(int i = 0; i < v.size(); i++) { 50 for(int j = k; j >= v[i]; j--) { 51 dp[j] |= dp[j-v[i]]; 52 } 53 } 54 return dp[k] ? "Possible" : "Impossible"; 55 } 56 57 // BEGIN CUT HERE 58 public: 59 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); if ((Case == -1) || (Case == 6)) test_case_6(); if ((Case == -1) || (Case == 7)) test_case_7(); if ((Case == -1) || (Case == 8)) test_case_8(); if ((Case == -1) || (Case == 9)) test_case_9(); if ((Case == -1) || (Case == 10)) test_case_10(); } 60 private: 61 template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 62 void verify_case(int Case, const string &Expected, const string &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } 63 void test_case_0() { int Arg0 = 4; int Arg1 = 2; int Arr2[] = {0,1,2,3}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,3,0}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Impossible"; verify_case(0, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 64 void test_case_1() { int Arg0 = 4; int Arg1 = 4; int Arr2[] = {0,1,2,3}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,3,0}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(1, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 65 void test_case_2() { int Arg0 = 4; int Arg1 = 2; int Arr2[] = {0,1,2,3}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {2,3,0,1}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(2, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 66 void test_case_3() { int Arg0 = 4; int Arg1 = 3; int Arr2[] = {0,1,2,3}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {2,3,0,1}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Impossible"; verify_case(3, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 67 void test_case_4() { int Arg0 = 3; int Arg1 = 3; int Arr2[] = {0,1,2}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,0}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(4, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 68 void test_case_5() { int Arg0 = 3; int Arg1 = 2; int Arr2[] = {0,1,2}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,0}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Impossible"; verify_case(5, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 69 void test_case_6() { int Arg0 = 6; int Arg1 = 1; int Arr2[] = {0,1,4}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,5}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(6, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 70 void test_case_7() { int Arg0 = 6; int Arg1 = 2; int Arr2[] = {0,1,4}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,5}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(7, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 71 void test_case_8() { int Arg0 = 6; int Arg1 = 3; int Arr2[] = {0,1,4}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,5}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(8, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 72 void test_case_9() { int Arg0 = 6; int Arg1 = 6; int Arr2[] = {0,1,4}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2,5}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(9, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 73 void test_case_10() { int Arg0 = 6; int Arg1 = 6; int Arr2[] = {1}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {2}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); string Arg4 = "Possible"; verify_case(10, Arg4, SplitParticles(Arg0, Arg1, Arg2, Arg3)); } 74 75 // END CUT HERE 76 77 }; 78 79 // BEGIN CUT HERE 80 int main() 81 { 82 DarkMatterParticles ___test; 83 ___test.run_test(-1); 84 return 0; 85 } 86 // END CUT HERE