codeforces 1019 A. Elections
你是一个竞选某个职位的人,编号为1号,同时还有m-1个人和你一块竞选
有m个人在投票,每个人投向pi,你可以用ci的代价让他投其他任何一个人
你竞选成功的条件是你获得的选票个数严格大于其余人的选票个数
输出最小代价
1≤n,m≤3000
1≤pi≤m, 1≤ci≤10^9
首先改变选票的人的话一定是指向自己
那么只需要枚举自己获得多少张选票即可,暴力扫一下更新最小值就行了

1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 3010; 5 typedef long long ll; 6 7 int n, m; 8 9 ll ans = 1ll << 60; 10 11 vector<ll> pak[N]; 12 13 int main() { 14 scanf("%d%d", &n, &m); 15 for(int i = 1, x, y ; i <= n ; ++ i) { 16 scanf("%d%d", &x, &y); 17 pak[x].push_back(y); 18 } 19 for(int x = 1 ; x <= m ; ++ x) if(pak[x].size()) sort(pak[x].begin(), pak[x].end(), greater<ll>()); 20 for(int i = pak[1].size() ; i <= n ; ++ i) { 21 priority_queue<ll, vector<ll>, greater<ll> > pq; 22 ll sum = 0, cnt = i - pak[1].size(); 23 for(int j = 2 ; j <= m ; ++ j) { 24 vector<ll> tmp = pak[j]; 25 while(tmp.size() && tmp.size() >= i) { 26 -- cnt; 27 sum += tmp.back(); 28 tmp.pop_back(); 29 } 30 while(tmp.size()) { 31 pq.push(tmp.back()); 32 tmp.pop_back(); 33 } 34 } 35 while(cnt > 0) -- cnt, sum += pq.top(), pq.pop(); 36 if(cnt <= 0) ans = min(ans, sum); 37 } 38 printf("%lld\n", ans); 39 }