由于题面太长就直接挂链接了
考虑网络流,我们将前个的最优匹配的图给存下来,对于第一问,直接暴力枚举他是第几志愿的,然后连边跑一下,看是否有增广,这样就做完了第一问
对于第二问,如果他的最优志愿小于等于,那么答案就是,否则考虑二分他前进的排名,然后将到的志愿全部连上边,再在上面的网络流图中判断一下是否增广即可
//Created Time:2020年06月07日 星期日 16时04分54秒 #include <queue> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 202 #define vec vector<int> #define oo 999999999 using namespace std; int n, m, S, T; int b[N], res[N], dis[N << 1], tmp[N << 1]; vec p[N][N]; struct edge{ int to, nxt, f; }; struct graph{ int cnt; int fir[N << 1], cur[N << 1]; edge e[N * 50]; void operator = (graph &x){ cnt = x.cnt; memcpy(fir, x.fir, (T + 1) << 2); for(int i = 0; i <= cnt; ++i) e[i] = x.e[i]; return ; } void add(int u, int v, int f){ e[++cnt] = (edge){v, fir[u], f}; fir[u] = cnt; e[++cnt] = (edge){u, fir[v], 0}; fir[v] = cnt; return ; } bool bfs(){ queue<int> Q; memset(dis, -1, (T + 1) << 2); dis[S] = 0; Q.push(S); while(!Q.empty()){ int u