C - Justice(优先队列+并查集)

Posted qq-1585047819

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C - Justice(优先队列+并查集)相关的知识,希望对你有一定的参考价值。

Put simply, the Justice card represents justice, fairness, truth and the law. You are being called to account for your actions and will be judged accordingly. If you have acted in a way that is in alignment with your Higher Self and for the greater good of others, you have nothing to worry about. However, if you have
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 解题思路:优先队列+并查集 具体看代码

技术图片
 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 
View Code

 

以上是关于C - Justice(优先队列+并查集)的主要内容,如果未能解决你的问题,请参考以下文章

并查集加优先队列

[POJ1456]Supermarket(贪心 + 优先队列 || 并查集)

“玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)

优先队列 + 并查集 + 字典树 + 树状数组 + 线段树 + 线段树点更新 + KMP +AC自动机 + 扫描线

ZOJ - 4109 - Welcome Party (并查集 + BFS + 优先队列)

HDU 1233 还是畅通工程(最小生成树, Prim+优先队列 || Kruskal+并查集)