Skip to content

Instantly share code, notes, and snippets.

@Baekjoon
Created October 24, 2015 01:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Baekjoon/000d1d3e72f8ded33d94 to your computer and use it in GitHub Desktop.
Save Baekjoon/000d1d3e72f8ded33d94 to your computer and use it in GitHub Desktop.
1031
#include <iostream>
#include <numeric>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <queue>
using namespace std;
struct MCMF {
struct Edge {
int to;
int capacity;
int cost;
Edge *rev;
Edge(int to, int capacity, int cost) : to(to), capacity(capacity), cost(cost) {
}
};
int n;
int source, sink;
vector<vector<Edge *>> graph;
vector<bool> check;
vector<int> distance;
vector<pair<int,int>> from;
int inf = 10000000;
MCMF(int n, int source, int sink) : n(n), source(source), sink(sink) {
graph.resize(n);
check.resize(n);
from.resize(n, make_pair(-1,-1));
distance.resize(n);
};
void add_edge(int u, int v, int cap, int cost) {
Edge *ori = new Edge(v,cap,cost);
Edge *rev = new Edge(u,0,-cost);
ori->rev = rev;
rev->rev = ori;
graph[u].push_back(ori);
graph[v].push_back(rev);
}
void add_edge_from_source(int v, int cap, int cost) {
add_edge(source, v, cap, cost);
}
void add_edge_to_sink(int u, int cap, int cost) {
add_edge(u, sink, cap, cost);
}
bool spfa(int &total_flow, int &total_cost) {
fill(check.begin(), check.end(), false);
fill(distance.begin(), distance.end(), inf);
fill(from.begin(), from.end(), make_pair(-1,-1));
distance[source] = 0;
queue<int> q;
q.push(source);
while (!q.empty()) {
int x = q.front();
q.pop();
check[x] = false;
for (int i=0; i<graph[x].size(); i++) {
auto e = graph[x][i];
int y = e->to;
if (e->capacity > 0 && distance[x] + e->cost < distance[y]) {
distance[y] = distance[x] + e->cost;
from[y] = make_pair(x,i);
if (!check[y]) {
q.push(y);
check[y] = true;
}
}
}
}
if (distance[sink] == inf) {
return false;
}
int x = sink;
int c = graph[from[x].first][from[x].second]->capacity;
while (from[x].first != -1) {
if (c > graph[from[x].first][from[x].second]->capacity) {
c = graph[from[x].first][from[x].second]->capacity;
}
x = from[x].first;
}
x = sink;
while (from[x].first != -1) {
Edge *e = graph[from[x].first][from[x].second];
e->capacity -= c;
e->rev->capacity += c;
x = from[x].first;
}
total_flow += c;
total_cost += c*distance[sink];
return true;
}
pair<int,int> flow() {
int total_flow = 0;
int total_cost = 0;
while (spfa(total_flow, total_cost));
return make_pair(total_flow, total_cost);
}
};
int main() {
int n,m;
cin >> n >> m;
vector<int> a(n), b(m);
for (int i=0; i<n; i++) cin >> a[i];
for (int j=0; j<m; j++) cin >> b[j];
int sum1=0, sum2=0;
sum1 = accumulate(a.begin(),a.end(),0);
sum2 = accumulate(b.begin(),b.end(),0);
if (sum1 != sum2) {
cout << -1 << '\n';
return 0;
}
MCMF mcmf(n+m+2,n+m,n+m+1);
for (int i=0; i<n; i++) {
mcmf.add_edge_from_source(i,a[i],0);
}
for (int j=0; j<m; j++) {
mcmf.add_edge_to_sink(n+j,b[j],0);
}
int cost = n*m-1;
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
mcmf.add_edge(i,n+j,1,(1<<cost));
cost--;
}
}
auto temp = mcmf.flow();
if (temp.first != sum1) {
cout << -1 << '\n';
return 0;
}
vector<vector<int>> ans(n,vector<int>(m));
for (int i=0; i<n; i++) {
for (auto e : mcmf.graph[i]) {
if (e->cost > 0) {
if (e->capacity == 0) {
ans[i][(e->to) - n] = 1;
}
}
}
}
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
cout << ans[i][j];
}
cout << '\n';
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment