其他分享
首页 > 其他分享> > 【基础】CF1369E - DeadLee

【基础】CF1369E - DeadLee

作者:互联网

题意

有 \(n\) 种菜,第 \(i\) 种菜有 \(w_i\) 盘。有 \(m\) 个朋友,每个朋友有喜欢吃的两种菜 \(x_i,y_i\) ,每个朋友被叫来的时候,会分别尝试吃掉一盘 \(x_i,y_i\) ,假如一盘都没有吃到,则朋友会不开心。按某种顺序叫这些朋友各恰好一次,求是否有合法的方案使得所有的朋友都开心,假如有,则构造这种方案。

题解

设想,第 \(i\) 种菜总共有 \(s_i\) 个朋友喜欢吃,那么当 \(s_i\leq w_i\) 时,则这种菜关联的朋友永远不会不开心,那么把他们安排到最后吃,很有可能可以省下喜欢的另一盘菜 \(j\) (这一次会导致 \(s_j\) 下降而又有新的菜被放出来),按这个思路贪心。假如按这个思路贪心能够成功叫到的朋友数不足 \(m\) 个,则一定失败(剩下的没有被叫的朋友一定会不开心,但是这个很不好证明)。

const int MAXN = 2e5;
 
int n, m;
int w[MAXN + 5];
int x[MAXN + 5];
int y[MAXN + 5];
unordered_set<int> s[MAXN + 5];
 
bool vis[MAXN + 5];
stack<int> S;
queue<int> Q;
 
void solve() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &w[i]);
    for(int i = 1; i <= m; ++i) {
        scanf("%d%d", &x[i], &y[i]);
        s[x[i]].insert(i);
        s[y[i]].insert(i);
    }
    for(int i = 1; i <= n; ++i) {
        if((int)s[i].size() <= w[i]) {
            Q.push(i);
            vis[i] = 1;
        }
    }
    while(!Q.empty()) {
        int u = Q.front();
        Q.pop();
        for(const int &val : s[u]) {
            S.push(val);
            int v = (x[val] == u) ? y[val] : x[val];
            s[v].erase(val);
            if(vis[v] == 0 && (int)s[v].size() <= w[v]) {
                Q.push(v);
                vis[v] = 1;
            }
        }
    }
    if(S.size() < m) {
        puts("DEAD");
        return;
    }
    puts("ALIVE");
    while(!S.empty()) {
        printf("%d ", S.top());
        S.pop();
    }
    puts("");
    return;
}

标签:开心,int,基础,朋友,CF1369E,MAXN,假如,种菜,DeadLee
来源: https://www.cnblogs.com/purinliang/p/13759805.html