Created
September 21, 2016 13:57
-
-
Save yurahuna/52857313eece71a36cfdad8601b316c9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define dame cout << "NO" << endl; return 0 | |
struct edge { int to, cap, rev; }; | |
const int MAX_V = 110; | |
vector<edge> G[MAX_V]; | |
int level[MAX_V]; | |
int iter[MAX_V]; | |
void add_edge(int from, int to, int cap) { | |
G[from].emplace_back((edge){to, cap, (int)G[to].size()}); | |
G[to].emplace_back((edge){from, 0, (int)G[from].size() - 1}); | |
} | |
void bfs(int s) { | |
memset(level, -1, sizeof(level)); | |
queue<int> que; | |
level[s] = 0; | |
que.push(s); | |
while (!que.empty()) { | |
int v = que.front(); que.pop(); | |
for (int i = 0; i < G[v].size(); i++) { | |
edge &e = G[v][i]; | |
if (e.cap > 0 && level[e.to] < 0) { | |
level[e.to] = level[v] + 1; | |
que.push(e.to); | |
} | |
} | |
} | |
} | |
int dfs(int v, int t, int f) { | |
if (v == t) return f; | |
for (int &i = iter[v]; i < G[v].size(); i++) { | |
edge &e = G[v][i]; | |
if (e.cap > 0 && level[v] < level[e.to]) { | |
int d = dfs(e.to, t, min(f, e.cap)); | |
if (d > 0) { | |
e.cap -= d; | |
G[e.to][e.rev].cap += d; | |
return d; | |
} | |
} | |
} | |
return 0; | |
} | |
int max_flow(int s, int t) { | |
int flow = 0; | |
for (;;) { | |
bfs(s); | |
if (level[t] < 0) return flow; | |
memset(iter, 0, sizeof(iter)); | |
int f; | |
while ((f = dfs(s, t, inf)) > 0) { | |
flow += f; | |
} | |
} | |
} | |
signed main() { | |
std::ios::sync_with_stdio(false); | |
std::cin.tie(0); | |
int n; | |
cin >> n; | |
vi a(n + 1), b(n + 1); | |
rep(i, n + 1) cin >> a[i]; | |
rep(i, n + 1) cin >> b[i]; | |
vi out, in; | |
rep(i, n + 1) { | |
rep(j, a[i]) { | |
in.emplace_back(i); | |
} | |
rep(j, b[i]) { | |
out.emplace_back(i); | |
} | |
} | |
// 頂点はn個ずつないとだめ、入次数と出次数の総和が一致していないとダメ | |
if (in.size() != n || out.size() != n || accumulate(all(in), 0) != accumulate(all(out), 0)) { | |
dame; | |
} | |
// 流すか・・・ | |
rep(i, n) { | |
rep(j, n) { | |
add_edge(i, n + j, 1); | |
} | |
} | |
const int s = 2 * n, t = s + 1; | |
rep(i, n) { | |
add_edge(s, i, out[i]); | |
} | |
rep(j, n) { | |
add_edge(n + j, t, in[j]); | |
} | |
int F = max_flow(s, t); | |
int D = accumulate(all(out), 0); | |
// フローを流しきれなかったらだめ | |
if (F < D) { | |
dame; | |
} | |
vvi ans(n, vi(n)); | |
rep(i, n) { | |
for (auto e : G[i]) { | |
if (n <= e.to && e.to < 2 * n && e.cap == 0) { | |
int j = e.to - n; | |
ans[i][j] = 1; | |
} | |
} | |
} | |
cout << "YES" << endl; | |
rep(i, n) { | |
rep(j, n) { | |
cout << ans[i][j] << (j != n - 1 ? " " : ""); | |
} | |
cout << endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment