【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
**/

 

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