思路:把两种颜色先按值sort一下,最小值肯定是叶子,然后把这个叶子和另外一中颜色的一个最小值的节点连接起来,再把这个节点变成叶子,把值减掉就可以了。
如下图:
代码1:
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; struct node { int val,id; bool operator <(node &a) { return val<a.val; } }a[N],b[N]; int main() { int n; int c1=0,c2=0; int col,val; cin>>n; for(int i=1;i<=n;i++) { cin>>col>>val; if(col) { b[c2].id=i; b[c2++].val=val; } else { a[c1].id=i; a[c1++].val=val; } } sort(a,a+c1); sort(b,b+c2); int l1=0,l2=0; int id0,id1; while(l1<c1&&l2<c2) { id0=a[l1].id; id1=b[l2].id; if(a[l1].val<b[l2].val) { cout<<a[l1].id<<' '<<b[l2].id<<' '<<a[l1].val<<endl; b[l2].val-=a[l1].val; l1++; if(l1>=c1)l2++;//如果其中一种颜色没了,那么最后一个连的另外一种颜色的节点就没有节点连了(也就是叶子结点) } else { cout<<a[l1].id<<' '<<b[l2].id<<' '<<b[l2].val<<endl; a[l1].val-=b[l2].val; l2++; if(l2>=c2)l1++; } } while(l1<c1)//所有剩下的节点和最后一个另外一种颜色连 { cout<<id1<<' '<<a[l1].id<<' '<<a[l1].val<<endl; l1++; } while(l2<c2) { cout<<id0<<' '<<b[l2].id<<' '<<b[l2].val<<endl; l2++; } return 0; }
代码2(写残版):
我居然用了优先队列,患上STL综合症的我脑残了。
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; struct node { int col; int val; int id; friend bool operator>(node a,node b) { return a.val>b.val; } }a[N]; int main() { int n; priority_queue<node,vector<node>,greater<node> >q0,q1; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].col>>a[i].val; a[i].id=i; if(a[i].col)q1.push(a[i]); else q0.push(a[i]); } int id0,id1; while(q0.size()&&q1.size()) { node temp0=q0.top(); node temp1=q1.top(); id0=temp0.id; id1=temp1.id; if(temp0.val<temp1.val) { q0.pop(); q1.pop(); cout<<temp0.id<<' '<<temp1.id<<' '<<temp0.val<<endl; temp1.val-=temp0.val; if(q0.size())q1.push(temp1); } else { q0.pop(); q1.pop(); cout<<temp0.id<<' '<<temp1.id<<' '<<temp1.val<<endl; temp0.val-=temp1.val; if(q1.size())q0.push(temp0); } } while(q0.size()) { node temp=q0.top(); q0.pop(); cout<<temp.id<<' '<<id1<<' '<<temp.val<<endl; } while(q1.size()) { node temp=q1.top(); q1.pop(); cout<<temp.id<<' '<<id0<<' '<<temp.val<<endl; } return 0; }