【基础】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