题意:有n双鞋,给定其分别的售价和尺码,保证所有鞋的尺码是不用的,有m个人来买鞋,给定其脚的大小以及手里的钱,他可以买跟脚号码相等或者大一号的鞋,同时需要保证手里的钱足够,问最多卖出的营业额是多少
因为每双鞋的尺码是不一样的,所以每个人最多有两种购买的可能,一边是顾客,一边是鞋,用map建成二分图,然后用匈牙利求解即可
但是为了保证营业额最大,首先要将鞋的售价降序排序,这样可以保证最优解
用前向星就tle,用vector就过了。。有点迷。。。
#include <iostream>
#include <map>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#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<int> 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 <int, int> 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;
}