结合代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int MAXN=1e5+5; 5 vector <int>pre[MAXN]; 6 struct node{ 7 int w;int sign; 8 bool operator <(const node &b)const{ 9 return w<=b.w; 10 } 11 }a[MAXN]; 12 int vis[MAXN]; 13 void dfs(int start){ 14 vis[start]=1; 15 for(int i=0;i<pre[start].size();i++){ 16 dfs(pre[start][i]); 17 } 18 } 19 priority_queue <node >Q; 20 /*用一个优先队列维护最小的两个元素,每次都取最小的两个元素,如果这两个元素相等那么就 可以合并 , 21 否则就不能合并,不能合并把较小的数扔掉,较大的继续入队,直到元素只剩下两个,看着两个元素是不都比1小,是的话那么就可行 22 ,关于记录,用了pre向量,合并的话,随便选择一个,把另一个的序号加到这个的pre中,因为这个元素可能被多次合并,所以才采用的向量特判, 23 可以记录多个,然后注意n<1的特判*/ 24 int main() 25 { 26 int t;cin>>t;int cnt=1; 27 while(t--) 28 { 29 memset(vis,0,sizeof(vis)); 30 int n;cin>>n; 31 for(int i=1;i<=n;i++) 32 { 33 pre[i].clear(); 34 scanf("%d",&a[i].w); 35 a[i].sign=i; 36 Q.push(a[i]); 37 } 38 if(Q.size()<2) 39 { 40 while(!Q.empty()) 41 { 42 Q.pop(); 43 } 44 printf("Case %d: NO\n",cnt++); 45 continue; 46 } 47 else 48 { 49 while(Q.size()>2) 50 { 51 node s1=Q.top();Q.pop(); 52 node s2=Q.top();Q.pop(); 53 if(s1.w==s2.w) 54 { 55 pre[s1.sign].push_back(s2.sign); 56 s1.w--; 57 Q.push(s1); 58 }else 59 { 60 if(s1.w<s2.w) 61 { 62 Q.push(s1); 63 }else 64 { 65 Q.push(s2); 66 } 67 } 68 } 69 } 70 node m1=Q.top();Q.pop();node m2=Q.top();Q.pop(); 71 if(m1.w<=1&&m2.w<=1) 72 { 73 dfs(m1.sign); 74 printf("Case %d: YES\n",cnt++); 75 for(int i=1;i<=n;i++) 76 { 77 if(vis[i]==0) 78 printf("0"); 79 else printf("1"); 80 } 81 cout <<endl; 82 while(!Q.empty()) Q.pop(); 83 84 }else 85 { 86 while(!Q.empty()) Q.pop(); 87 printf("Case %d: NO\n",cnt++); 88 } 89 } 90 return 0; 91 }