C - Justice(优先队列+并查集)
acted in a way that is out of alignment, you will be called out and required to own up to your actions. If this has you shaking in your boots, know that the Justice card isn’t as black and white as you may think.
On the table there are n weights. On the body of the i-th weight carved a positive integer kiki , indicating that its weight is 12ki12ki gram. Is it possible to divide the n weights into two groups and make sure that the sum of the weights in each group is greater or equal to 1212 gram? That’s on your call. And please tell us how if possible.
InputIn the first line of the input there is a positive integer TT
(1 ≤ TT
≤ 2000), indicating there are TT
testcases.
In the first line of each of the TT
testcases, there is a positive integer nn
(1 ≤ nn
≤ 105105
, ∑n ≤ 7 × 105105
), indicating there are nn
weights on the table.
In the next line, there are nn
integers kiki
(1 ≤ ki ≤ 109109
), indicating the number carved on each weight.OutputFor each testcase, first print Case ii
: ANSWER in one line, ii
indicating the case number starting from 11
and ANSWER should be either YES or NO, indicating whether or not it is possible to divide the weights. Pay attention to the space between : and ANSWER.
If it’s possible, you should continue to output the dividing solution by print a 0/1 string of length nn
in the next line. The ii
-th character in the string indicating whether you choose to put the i-th weight in group 0 or group 1.Sample Input
3 3 2 2 2 3 2 2 1 2 1 1
Sample Output
Case 1: NO Case 2: YES 001 Case 3: YES 10
题目意思:能不能分成两组使得和大于等于1/2 解题思路:优先队列+并查集 具体看代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 using namespace std; 6 7 const int N=1e5+5; 8 9 int arr[N],vis[N]; 10 int n,t; 11 priority_queue<pair<int,int> > que; 12 13 int find_root(int x) { return arr[x]==x?x:arr[x]=find_root(arr[x]); } 14 int union_set(int x,int y){ int xx=find_root(x),yy=find_root(y);if(xx>yy) swap(xx,yy); arr[xx]=yy; return yy; } 15 //大的放到小的上面 16 int main(){ 17 ios::sync_with_stdio(false); 18 int jishu=0; 19 cin>>t; 20 while(t--){ 21 cin>>n; 22 for(int i=1;i<=N-1;i++) arr[i]=i; //并查集 23 while(!que.empty()) que.pop(); 24 memset(vis,0,sizeof(vis)); 25 for(int i=1,d;i<=n;i++){ 26 cin>>d; 27 que.push({d,i}); 28 } 29 while(!que.empty()&&que.top().first>1){ 30 int fi=que.top().first,se=que.top().second; 31 que.pop(); 32 if(fi!=que.top().first) continue; //没有相同的就舍弃就OK了 33 if(que.empty()) break; 34 int u=que.top().second;que.pop(); 35 int ee=union_set(se,u); 36 que.push({fi-1,ee}); 37 } 38 // while(!que.empty()) cout << que.top().first << " " << que.top().second << endl,que.pop(); 39 // cout << endl; 40 cout << "Case " << ++jishu << ": "; 41 if(que.size()<2) {cout << "NO" << endl;continue;} 42 int ee=que.top().second; 43 for(int i=1;i<=n;i++){ 44 if(find_root(i)==ee) vis[i]=1; 45 else vis[i]=0; 46 } 47 cout << "YES" << endl; 48 for(int i=1;i<=n;i++) cout << vis[i]; 49 cout << endl; 50 } 51 return 0; 52 }