Codeforces Round #744 (Div. 3) D. Productive Meeting(优先队列)
https://codeforces.com/contest/1579/problem/D
n个人被邀请。任何时刻,任何两个人都可以退后一步,私下谈谈。同样的两个人可以在每次会议中谈几次(想谈几次就谈几次)。
每个人的社交能力都有限。第i个人的社交度是一个非负整数ai。这意味着在ai讲话之后,这个人离开会议(并且不再和任何人讲话)。如果ai=0,第i个人在会议开始后立即离开。
如果会议期间举行了尽可能多的会谈,那么会议就被认为是最有成效的。
给你一组社交能力a,决定哪些人应该互相交谈,这样交谈的总次数就尽可能多。
input
8
2
2 3
3
1 2 3
4
1 2 3 4
3
0 0 2
2
6 2
3
0 0 2
5
8 2 0 1 1
5
0 1 0 0 6
output
2
1 2
1 2
3
1 3
2 3
2 3
5
1 3
2 4
2 4
3 4
3 4
0
2
1 2
1 2
0
4
1 2
1 5
1 4
1 2
1
5 2
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=200200,M=2002;
int main()
{
cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
int T=1;
cin>>T;
while(T--)
{
int n;
cin>>n;
priority_queue<PII> pq;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if(x>0) pq.push({x,i});//i这个位置上的谈话数量x
}
//优先队列排个序,小的放在前面,大的放在后面
vector<PII> vv;
while(pq.size()>1)
{
auto x=pq.top();
pq.pop();
auto y=pq.top();
pq.pop();
x.first--;
y.first--;
//谈话数量不断减少,这里是一对一对地减少
//所以如果有遗漏的,就放回去继续和下一个匹配
if(x.first>0) pq.push(x);
if(y.first>0) pq.push(y);
//立马记录下标
vv.push_back({x.second,y.second});
}
cout<<vv.size()<<endl;
for(int i=0;i<vv.size();i++)
{
cout<<vv[i].first<<" "<<vv[i].second<<endl;
}
}
return 0;
}