Codeforces1369 E. DeadLee(贪心+拓扑排序)

题意:

有 n 道菜,每道菜的数量为a(i) ,现在有m个人,每个人都有爱吃的两道菜x和y ,当第 i 个人来之后,会吃掉x和y各一份,如果x没有了的话,那么他只会选择吃掉一份y ,没有y同理,但是如果x和y同时没有的话,就不合法。

问是否存在一种序列,使得按照序列顺序,每个人都能吃到菜。如果有,则输出一个合法序列。

数据范围:n<=2e5

解法:

统计每种菜的需求数sum(i),
1.如果sum(x)<=a(y),那么每个选择这个菜的人都能吃到,贪心的将他们放在序列的最后,
2.并假设他们喜欢的另一种食物y吃不到(sum(y)-=1,给其他人留了吃y的机会),然后跳转至1判断y重复操作

实现方法是对每种菜进行拓扑排序,先将sum(i)<=a(i)的菜入队,
当队列不为空的时候:
取出队头菜x,将所有选择菜x的人(x,y)丢到答案尾部,同时sum(y)-=1,如果sum(y)<=a(y),那么y入队。
记得开个标记数组保证每个点只入队一次

code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=2e5+5;
vector<pair<int,int> >g[maxm];
int mark[maxm];
int mark_idx[maxm];
int sum[maxm];
int a[maxm];
int n,m;
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=m;i++){
        int x,y;cin>>x>>y;
        sum[x]++;sum[y]++;
        g[y].push_back({x,i});
        g[x].push_back({y,i});
    }
    stack<int>ans;
    queue<int>q;
    for(int i=1;i<=n;i++){
        if(sum[i]<=a[i]){
            mark[i]=1;
            q.push(i);
        }
    }
    while(!q.empty()){
        int x=q.front();q.pop();
        for(auto i:g[x]){
            if(!mark_idx[i.second]){
                mark_idx[i.second]=1;
                ans.push(i.second);
            }
            if(mark[i.first])continue;
            sum[i.first]--;
            if(sum[i.first]<=a[i.first]){
                mark[i.first]=1;
                q.push(i.first);
            }
        }
    }
    if(ans.size()==m){
        puts("ALIVE");
        while(!ans.empty()){
            cout<<ans.top()<<' ';
            ans.pop();
        }
    }else{
        puts("DEAD");
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值