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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮