• CodeForces 1369E. DeadLee


    题意:这里有n种类型不同的食物,还有m个Lee的朋友。Lee有wi盘第i种类型的食物,并且每个朋友都有两种喜欢的类型的食物,第i个朋友喜欢xi和yi类型的食物。Lee将会按顺序叫他的每一个朋友过来吃食物,他会吃这两种食物的一盘,如果只存在一种他喜欢的食物,他会吃掉这种食物的一盘,如果都没有,他会吃了Lee,输出DEAD,否则输出ALIVE,并且输出吃的顺序。

    分析:吃的过程存在顺序,说明可能是一种拓扑关系,表示我们可以尝试使用图论的算法。前面的状态会影响后面的状态,因此我们可以先看看能不能采用贪心,对于每种食物的需求量s[i],如果s[i] <= w[i],说明这个食物的分量很足,我们可以放到后面吃,这样是一个不错的决策。比如说我们放到后面吃的话,那么这个食物在前面被人吃了话,比如前面一个人会吃一种食物,顺带把这个食物也吃了,那么后面的人可能只能吃一种的话,那么可能不会产生吃失败的场面,那么它被放在后面可能还会剩很多食物。因此,我们可以用拓扑排序,把那些分量很足的食物,即w[i] >= s[i]的食物入队,当一个食物出队的时候,我们就标记吃这个食物的人已经吃过,并放进答案数组,最后还要把数组翻转一下,因为我们是从后往前拓扑的。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    using PII = pair<int, int>;
    const int N = 100005;
    const int M = 200005;
    int w[N], s[N];
    int q[M];
    
    vector<PII> e[N];
    //标记删除的点
    bool st[M];
    
    int main()
    {
        //食物的类型数量,Lee的朋友数量
        int n, m;
        scanf("%d%d", &n, &m);
        
        //每种类型的食物数量
        for(int i = 0; i < n; ++i)
        {
            scanf("%d", &w[i]);
        }
    
        //memset(h, -1, sizeof h);
        for(int i = 0; i < m; ++i)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            --u, --v;
            e[u].push_back({v, i});
            e[v].push_back({u, i});
            ++s[u], ++s[v];
        }
    
        int hh = 0, tt = -1;
    
        //最后吃需求量比补给量少的食物,会对前面的吃食产生良好的影响
        for(int i = 0; i < n; ++i)
            if(w[i] >= s[i])
                q[++tt] = i;
    
        vector<int> res;
    
        while(hh <= tt)
        {
            int u = q[tt--];
            for(auto item : e[u])
            {
                int v = item.first, i = item.second;
                if(st[i]) continue;
                st[i] = true;
                res.push_back(i);
                if(--s[v] == w[v])
                    q[++tt] = v;
            }
    
        }
    
        if(res.size() < m)
        {
            puts("DEAD");
            return 0;
        }
    
        puts("ALIVE");
    
        reverse(res.begin(), res.end());
    
        for(int i = 0; i < res.size(); ++i)
            printf("%d ", res[i] + 1);
    
        return 0;
    }
    
    
  • 相关阅读:
    十一、GUI设计-记事本程序
    十、GUI编程
    OSI七层模型中各层的数据名称
    使用了frame的页面如何整体进行跳转,而不是仅frame跳转
    MySQL脏读、不可重复读、幻读
    博客园后台搜索自己的博客
    完整的ELK+filebeat+kafka笔记
    InnoDB引擎中的索引与算法
    Docker pull下载出现 error pulling image configuration:
    多台服务器通过docker搭建ELK集群
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13210524.html
Copyright © 2020-2023  润新知