Loading

牛客挑战赛52 A. 深海少女(贪心)

题目描述

现给定 n 个数 {ai}{ai} 和 m 个关系。

第 i 个关系形如 (x, y)。请你重排 {ai}{ai},使得 ∑i=1m(axi−ayi)i=1∑m(axi−ayi) 最小。
你只需要输出这个最小值即可。

输入描述:

一行两个数 n,m(1≤n,m≤105)n,m(1≤n,m≤105)。

第二行,n 个数,表示 {ai}i=1n(1≤ai≤109){ai}i=1n(1≤ai≤109)。

接下来 m 行,每行两个数 xi,yi(1≤xi,yi≤n)xi,yi(1≤xi,yi≤n)。

输出描述:

一行一个数,表示答案。

示例1

输入

复制

3 3
3 3 2 
1 2
3 2
1 2

输出

复制

2

贪心。把\(\Sigma_{i=1}^n(a_{x_i}-a_{y_i})\)拆开为\(\Sigma_{i=1}^na_{x_i}-\Sigma_{i=1}^na_{y_i}\),这样就可以选择这么一种贪心策略:每个xi位置-1,每个yi位置+1,最后把a从大到小填充到值从大到小的每个位置即可。

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#define int long long
using namespace std;
int n, m, a[100005], ans[100005];
int cnt[100005];
struct node {
    int id, cnt;
    bool operator < (const node& o) const {
        return cnt < o.cnt;
    }
};
signed main() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);
    memset(cnt, 0, sizeof(cnt));
    vector<pair<int,int> > rel;
    for(int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        cnt[x]--;
        cnt[y]++;
        rel.push_back(make_pair(x, y));
    }
    vector<node> v;
    for(int i = 1; i <= n; i++) { 
        node tmp;
        tmp.id = i, tmp.cnt = cnt[i];
        v.push_back(tmp);
    }
    sort(v.begin(), v.end());
    for(int i = 0; i < v.size(); i++) {
        ans[v[i].id] = a[i + 1];
    }
    int aans = 0;
    for(auto x : rel) {
        aans += ans[x.first] - ans[x.second];
    }
    cout << aans;
    return 0;
}
posted @ 2021-09-24 20:07  脂环  阅读(163)  评论(0编辑  收藏  举报