【Codeforces 1369E】DeadLee 思维贪心

https://codeforces.ml/contest/1369/problem/E

题目大意:

有m道菜(每道菜有ai个),n个人,每个人有两个要吃的菜,问能否安排一个合法的吃饭顺序,使得每个人都至少有一道菜可以吃

题目思路:

想了一天唉..

经过多方对比,发现这个思路,时间和空间都是最优的,并且比较好理解,就写一下当前的思路吧。

倒着贪心

就考虑最后一个应该放什么

最后一个放的应该满足一个要求:即就算前面都吃了属于他的菜,他依然可以有菜吃

所以统计每道菜的总需求量(w[i]),与当前每道菜的供给量作为对比(ai)

如果 w[i] <= a[i] ,那么表示吃这个菜的人,无论如何都有菜吃。

那么吃这第i道菜的人,就完全可以不吃另一道菜了,即另一道菜需求量减1

如果有新的w[i] <= a[i] 那么就再倒着吃这道菜 按照之前的方式进行更新

如果存在 没有w[i] <= a[i] 即 剩下的所有菜需求量都大于供给量 那么一定不能成功分配了(因为至少每个人都要吃一个菜嘛)

Code:

/*** keep hungry and calm CoolGuang!***/
#include <bits/stdc++.h>
#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF=2e18;
const int maxn=1e6+6;
const int mod=1e9+6;
const double eps=1e-15;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
ll num[maxn];
ll w[maxn];
vector<int>ans;
vector<pair<int,int>>v[maxn];
int vis[maxn];
int main()
{
    memset(vis,0,sizeof(vis));
    read(n);read(m);
    for(int i=1;i<=n;i++) read(num[i]);
    for(int i=1;i<=m;i++){
        ll x,y;read(x);read(y);
        w[x]++;w[y]++;
        v[x].push_back({y,i});
        v[y].push_back({x,i});
    }
    queue<int>q;
    for(int i=1;i<=n;i++){
        if(w[i] <= num[i]) q.push(i);
    }
    while(!q.empty()){
        int u = q.front();q.pop();
        for(auto x:v[u]){
            if(!vis[x.second]){
                vis[x.second] = 1;
                ans.push_back(x.second);
                if(--w[x.first]<=num[x.first]){
                    q.push(x.first);
                }
            }
        }
    }
    if(ans.size()<m) printf("DEAD\n");
    else {
        printf("ALIVE\n");
        reverse(ans.begin(),ans.end());
        for(int x:ans){
            printf("%d ",x);
        }
        printf("\n");
    }
    return 0;
}

/**
5
7 3
1 2 3 4 5 6 7
1 2 4
**/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章