题意:有n双鞋,给定其分别的售价和尺码,保证所有鞋的尺码是不用的,有m个人来买鞋,给定其脚的大小以及手里的钱,他可以买跟脚号码相等或者大一号的鞋,同时需要保证手里的钱足够,问最多卖出的营业额是多少
因为每双鞋的尺码是不一样的,所以每个人最多有两种购买的可能,一边是顾客,一边是鞋,用map建成二分图,然后用匈牙利求解即可
但是为了保证营业额最大,首先要将鞋的售价降序排序,这样可以保证最优解
用前向星就tle,用vector就过了。。有点迷。。。
#include #include #include #include #include #include #define rep(i, j, k) for (int i = j; i <= k; i++) #define maxn 100009 #define ll long long using namespace std; int n, to[maxn * 6], Next[maxn * 6], head[maxn], match[maxn];//, vis[maxn]; int tot = 0; int m, ret; ll ans = 0; vector edge[maxn]; struct cadongllas { int money, size, num; }a[maxn], b[maxn]; void add (int u, int v) { //to[++tot] = v; Next[tot] = head[u]; head[u] = tot; edge[u].push_back (v); } bool dfs (int x) { //for (int i = head[x]; i; i = Next[i]) for (int i = 0; i < edge[x].size (); i++) if (match[edge[x][i]] != x) { if (match[edge[x][i]] == -1 || dfs (match[edge[x][i]])) { match[edge[x][i]] = x; return 1; } } return 0; } bool cmp (cadongllas x, cadongllas y) { return x.money > y.money; } int main () { map num; cin >> n; rep (i, 1, n) scanf ("%d%d", &a[i].money, &a[i].size), a[i].num = i; sort (a + 1, a + 1 + n, cmp); cin >> m; rep (i, 1, m) scanf ("%d%d", &b[i].money, &b[i].size); rep (i, 1, n) num[a[i].size] = i; rep (i, 1, m) { if (num[ b[i].size + 1] && b[i].money >= a[ num[ b[i].size + 1]].money) add (num[ b[i].size + 1], i); if (num[b[i].size] && b[i].money >= a[ num[b[i].size]].money) add (num[b[i].size], i); } memset (match, -1, sizeof (match)); rep (i, 1, n) { //memset (vis, 0, sizeof (vis)); if (dfs (i)) { ans += a[i].money * 1LL; ret++; } } cout << ans << endl << ret << endl; rep (i, 1, m) if (match[i] != -1) printf ("%d %d\n", i, a[match[i]].num); return 0; }