/**
HDU 6002 Game Leader
题意:有一个社交网络,每个玩家都有一个评分而且评分不同,一些玩家可以结交成朋友,朋友是相对而言的,意思就是说如果A是B的朋友,那么B也是A的朋友,
每个玩家都有一个评分排名,他们知道自己的排名以及自己朋友的排名, Tom有n个朋友, 他在n个朋友中的排名是R,现在已知Tom朋友列表中有M对朋友,排名为
Xi和排名为Yi的朋友互为朋友,还知道Tom列表中的排名为i的朋友,i在Ci个他的朋友的列表上评分占第一名,现在要求最少有多少个人是Tom的陌生人但是陌生人
的朋友列表上评分排第一名的是Tom的朋友
思路:要使满足条件的陌生人尽可能少,就是需要满足Tom朋友中排名第一的朋友与Tom的朋友形成尽可能的朋友关系,就是Tom的朋友A和Tom的朋友B是朋友,当A和B
能形成朋友关系时,必须满足:不存在一个Tom的朋友X,使得X和B有朋友关系而且X在Tom列表中的排名大于A,那么先从M对已知关系中记录排名为i的tom的朋友 和其
他Tom的朋友形成关系的最大排名,排名从后往前扫描,每次把i的 朋友也是Tom的朋友的最大排名记录,i能匹配在他之后的Tom的条件是i是那个Tom朋友已知关系的最
大排名,用一个优先队列维护即可。
**/
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<functional>
#include<algorithm>
#include<iostream>
typedef long long ll;
const int maxn = 1e5 + 10;
const int INF = 1e8;
const int mod = 1e9 + 7;
using namespace std;
int n, m, r, T, kase = 1;
int pa[maxn], tal[maxn];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d %d %d", &n, &m, &r);
for(int i = 1; i <= n; i++) {
pa[i] = min(i, r); cnt[i] = 0;
scanf("%d", &tal[i]);
}
for(int i = 0; i < m; i++) {
int x, y;
scanf("%d %d", &x, &y);
if(x < y) swap(x, y);
pa[x] = min(pa[x], y);
}
pa[r] = 1;
ll ans = 0;
priority_queue<int> que;
for(int i = n; i >= 1; i--) {
if(i != n) que.push(pa[i]);
while(tal[i] && !que.empty() && que.top() >= i) {
que.pop(); tal[i]--;
}
ans += tal[i];
if(i == n) que.push(pa[i]);
}
printf("Case #%d: %lld\n", kase++, ans);
}
return 0;
}
HDU 6002 Game Leader(贪心)
最新推荐文章于 2019-09-30 18:28:59 发布