Codeforces 1369 E. DeadLee —— 想法,贪心

This way

题意:

现在有n种菜,每种菜都有wi碟,你有m个朋友,每个朋友都有两种喜欢的菜,你按照某个排序让朋友一个一个来吃菜,如果现在桌上有这个朋友喜欢的菜,他就会每种都吃一碟,但是如果两种菜都没了,你就会死。问你最后你会不会死,如果不会输出这个排序。

题解:

假设喜欢吃第i种菜的总人数是si,如果si<=wi,那么就意味着喜欢吃第i种菜的人一定都可以吃到,于是我们将这些人往后排,我这里使用了栈来存储。然后对于这些人另一个喜欢吃的菜sj-1,这样依次到最后。如果有某个时候所有的si>wi的话,就是不可能了,因为假设所有的si=wi+1,那么对于第一个菜,有wi个人能吃到,然后最后一个人就要去别的地方竞争,到最后还是会有人吃不到菜。

#include
using namespace std;
#define ll long long
const int N=2e5+5;
int s[N],w[N],a[N],b[N];
bool vis[N];
vector<int>vec[N];
queue<int>Q;
stack<int>ans;
int main()
{
    int n,m;
    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",&a[i],&b[i]);
        vec[a[i]].push_back(i),vec[b[i]].push_back(i);
        s[a[i]]++,s[b[i]]++;
    }
    for(int i=1;i<=n;i++)
        if(s[i]&&s[i]<=w[i])
            Q.push(i);
    while(!Q.empty()){
        int u=Q.front();Q.pop();
        for(auto j:vec[u]){
            if(vis[j])continue;
            ans.push(j);
            vis[j]=1;
            int oth=a[j]==u?b[j]:a[j];
            s[oth]--;
            if(s[oth]==w[oth])
                Q.push(oth);
        }
    }
    if(ans.size()!=m)
        return 0*printf("DEAD\n");
    printf("ALIVE\n");
    while(!ans.empty())
        printf("%d ",ans.top()),ans.pop();
    return 0;
}

你可能感兴趣的:(想法,贪心)