返回顶部

2020-2021 ICPC Southwestern European Regional Contest (SWERC 2020) L. Restaurants (优先队列)

  • 题意:有\(n\)个人,\(m\)个餐馆,每个人都有自己想去的餐馆,按喜好顺序排列,同时餐馆也对这些想要来的顾客做了优先级排列,问你最后那些人能预定到餐馆。

  • 题解:这题咋一眼看是一个稳定婚姻匹配的裸题,但数据范围似乎不太行,我们先将所有人放到队列里,然后按顺序给他们安排餐馆(放入优先队列中,根据餐馆希望的优先级排序),如果当前安排的餐馆满了,就将餐馆优先级最低的那个人踢掉,再将这个人放入队列,下次看他的希望的下一个餐馆。

  • 代码

    #include <bits/stdc++.h>
    using namespace std;
    #define PII pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define ll long long
    #define ull unsigned long long
    const int N=1e6+10;
    
    int n,m;
    int c[N];
    unordered_map<int,int> rk[N];
    vector<int> cres[N],resp[N];
    queue<int> q;
    priority_queue<int> h[N];
    int p[N];
    
    int main(){
        cin>>n>>m;
        for(int i=1;i<=m;++i) cin>>c[i];
        getchar(); //fuck the '\n'
        for(int i=1;i<=n;++i){
            string s;
            getline(cin,s);
            int num=0;
            for(int j=0;j<(int)s.size();++j){
                if(j==(int)s.size()-1){
                    num=num*10+s[j]-'0';
                    cres[i].pb(num);
                    num=0;
                }
                else if(s[j]==' '){
                    cres[i].pb(num);
                    num=0;
                }
                else num=num*10+s[j]-'0';
            }
        }
        for(int i=1;i<=m;++i){
            string s;
            getline(cin,s);
            int num=0;
            for(int j=0;j<(int)s.size();++j){
                if(j==(int)s.size()-1){
                    num=num*10+s[j]-'0';
                    rk[i][num]=(int)resp[i].size();
                    resp[i].pb(num);
                    num=0;
                }
                else if(s[j]==' '){
                   rk[i][num]=(int)resp[i].size();
                   resp[i].pb(num);
                   num=0;
                }
                else num=num*10+s[j]-'0';
            }
        }
        for(int i=1;i<=n;++i) q.push(i);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            if(p[u]==(int)cres[u].size()) continue;
            int r=cres[u][p[u]];
            h[r].push(rk[r][u]);
            while((int)h[r].size()>c[r]){
                int v=resp[r][h[r].top()];
                h[r].pop();
                p[v]++;
                q.push(v);
            }
        }
        for(int i=1;i<=n;++i){
            if(p[i]<(int)cres[i].size()) printf("%d\n",i);
        }
        return 0;
    }
    
posted @ 2021-11-03 23:28  Rayotaku  阅读(224)  评论(0编辑  收藏  举报