RT,AC的那发是验证题解正确性的
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define D double
#define LD long double
#define LL long long
#define ULL unsigned long long
#define fi first
#define se second
#define mp make_pair
using namespace std;
bool nc[1010][1010];
char buf[1 << 23], *p1 = buf, *p2 = buf, obuf[1 << 23], *O = obuf;
#define getchar() (p1 == p2 &&(p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
inline int rd()
{
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch))
x = x * 10 + (ch ^ 48), ch = getchar();
return x * f;
}
const int N = 1e5 + 7, M = 1e7 + 7;
const LL inf = 1e18;
int n, S, T, h[N], hi[N], e[M], t[M], tot, d[N];
int s[N];
LL mxf, f[M];
inline void add(int x, int y, LL z, int o = 1)
{
e[++tot] = y, s[tot] = x, f[tot] = z, t[tot] = h[x], h[x] = tot;
if (o)
{
add(y, x, 0, 0);
}
return;
}
inline bool bfs()
{
for (int i = 1; i <= n; i++)
{
d[i] = 0;
}
queue<int> q;
q.push(S), d[S] = 1;
while (q.size())
{
int x = q.front();
q.pop();
for (int i = h[x]; i; i = t[i])
{
int y = e[i];
LL z = f[i];
if (d[y] || !z)
{
continue;
}
q.push(y);
d[y] = d[x] + 1;
if (y == T)
{
return 1;
}
}
}
return 0;
}
LL dinic(int x, LL nwf)
{
if (x == T)
{
return nwf;
}
LL rst = nwf;
for (int &i = hi[x]; i; i = t[i])
{
int y = e[i];
LL z = f[i];
if (d[y] != d[x] + 1 || !z)
{
continue;
}
LL k = dinic(y, min(z, rst));
if (!k)
{
d[y] = 0;
}
else
{
f[i] -= k;
f[i ^ 1] += k;
rst -= k;
}
if (!rst)
{
break;
}
}
return nwf - rst;
}
inline void Main()
{
while (bfs())
{
for (int i = 1; i <= n; i++)
{
hi[i] = h[i];
}
LL now;
while ((now = dinic(S, inf)))
{
mxf += now;
}
}
return;
}
inline void init(int _n, int _S, int _T)
{
n = _n, S = _S, T = _T, tot = 1, mxf = 0;
for (int i = 1; i <= n; i++)
{
h[i] = 0;
}
return;
}
int main()
{
int n;
cin >> n;
init(2 * n + 2, 2 * n + 1, 2 * n + 2);
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
add(i + n, 2 * n + 2, x);
}
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
add(2 * n + 1, i, x);
}
int m;
cin >> m;
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
nc[u][v] = 1;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i != j && !nc[i][j])
{
add(i, j + n, 1ll);
}
}
}
Main();
printf("%lld\n", mxf);
for (int i = 4 * n + 2; i <= tot; i++)
{
if (i % 2 == 0 && f[i] == 0)
{
printf("%d %d\n", s[i], e[i] - n);
}
}
return 0;
}