最小化代价(优先队列)

链接:https://www.nowcoder.com/acm/contest/112/A

现有n组人,m个地点,给出每组人的人数,每个地点可容纳的最大人数和选择的价格
要求一种方式,使得每组人都到一个各不相同的地点,最小化选择的价格
每个队伍的人都要在同一个地方每个地方只能有一个队伍

输入描述:

第一行n,m
第二行n个数,表示每组的人数
接下来m行,每行两个数,表示可容纳的最大人数和选择的价格

输出描述:

输出最小化选择的价格,无解输出-1
示例1

输入

3 4
2 3 4
1 2
2 3
3 4
4 5

输出

12

备注:

所有数据小于1e5
从大到小判断就可以了。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#pragma comment(linker, "/stck:1024000000,1024000000")
#define lowbit(x) (x&(-x))
#define max(x,y) (x>=y?x:y)
#define min(x,y) (x<=y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.1415926535897932384626433832
#define ios() ios::sync_with_stdio(true)
#define INF 0x3f3f3f3f
#define mem(a) ((a,0,sizeof(a)))
typedef long long ll;
vector<int>v[100005];
int a[100006];
priority_queue<int,vector<int>,greater<int> >q;
int n,m,x,y,cnt=0,ans=0;
int main()
{
    scanf("%d%d",&n,&m);
    memset(a,0,sizeof(a));
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        a[x]++;
    }
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&x,&y);
        v[x].push_back(y);
    }
    for(int i=100000;i>=1;i--)
    {
        for(int j=0;j<v[i].size();j++)
            q.push(v[i][j]);
        while(!q.empty() && a[i]>0)
        {
            int u=q.top();
            ans+=u;
            q.pop();
            cnt++;
            a[i]--;
        }
    }
    if(cnt>=n) printf("%d\n",ans);
    else printf("-1\n");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/shinianhuanniyijuhaojiubujian/p/9026729.html