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;
}
posted @ 2022-08-17 20:01  Vijurria  阅读(25)  评论(0编辑  收藏  举报