题目链接:https://codeforces.com/contest/1369/problem/E
题意:Lee邀请m位朋友来家里恰晚饭,每个朋友有两个喜欢吃的菜,轮流去厨房取菜,如果一个人进厨房的时候两个喜欢的菜都在,则会拿两个菜,只有一个喜欢的菜就拿一个,一个都没有的话就会把Lee吃掉,朋友进厨房的顺序由Lee决定,如果Lee能活下去就输出ALIVE并输出朋友进厨房的顺序,反之输出DEAD。
分析:根据贪心的思想,要尽可能的让更多的的人进去的时候只能吃一道菜。假设有b[i]个人喜欢吃第i道菜,如果b[i]<=w[i]的话,那么他们不管什么时候进厨房都是能吃到自己喜欢吃的菜的,所以让这些人在最后进厨房。这些人当中喜欢吃的第二道菜(假设这道菜为b[j])有两种情况,①b[j] <= w[j],那么和上面的一样,往后排。②b[j] > w[j],因为喜欢吃这道菜的人的另一个喜欢吃的菜已经供大于需了,所以这第二道菜他是可吃可不吃的,此时我们将第二道菜的需求b[j]-1再判断此时b[i]和w[i]的关系,如果b[j]==w[j],则说明贪心成功,喜欢吃b[j]这道菜的朋友也可以吃到自己喜欢吃的菜而不用吃Lee了。
#include<bits/stdc++.h> #include<vector> #include<map> #include<queue> #define LL long long #define INF (LL)1<<63-1 #define MOD 1000000007 using namespace std; const int N = 2e5 + 105; int w[N], b[N], vis[N]; int main() { int n, m, x, y; scanf("%d%d", &n, &m); for(int i = 0;i < n;i++) scanf("%d", &w[i]); vector<pair<int, int>> a[n]; for(int i = 0;i < m;i++) { scanf("%d%d", &x, &y); x--,y--; a[x].emplace_back(y, i); a[y].emplace_back(x, i); b[x]++, b[y]++; } queue<int> q; for(int i = 0;i < n;i++) { if(w[i] >= b[i]) q.push(i); } vector<int> ans; while(!q.empty()) { int tem = q.front(); q.pop(); for(auto it: a[tem]) { int type = it.first; int pos = it.second; if(vis[pos]) continue; vis[pos] = 1; ans.push_back(pos); if(--b[type] == w[type]) q.push(type); } } if(ans.size() < m) printf("DEAD "); else { printf("ALIVE "); for(int i = m-1;i >= 0;i--) printf("%d ", ans[i]+1); printf(" "); } return 0; }