zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    JS 继承
    Ajax 与 Comet
    JS事件对象
    JS事件处理程序
    在JavaScript中创建命名空间的几种写法
    DOM0 DOM2 DOM3
    html5脚本编程
    canvas画图
    R语言平均值和加权平均值
    pyqt5通过文本对话框打开文件
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13210524.html
Copyright © 2011-2022 走看看