HDU 6002 Game Leader(贪心)

/**
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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值