/* ******************************************************************************** */
#include <iostream> //
#include <cstdio> //
#include <cmath> //
#include <cstdlib> //
#include <cstring> //
#include <vector> //
#include <ctime> //
#include <deque> //
#include <queue> //
#include <algorithm> //
#include <map> //
using namespace std; //
//
#define pb push_back //
#define mp make_pair //
#define X first //
#define Y second //
#define all(a) (a).begin(), (a).end() //
#define foreach(a, i) for (typeof(a.begin()) i = a.begin(); i != a.end(); ++ i) //
#define fill(a, x) memset(a, x, sizeof(a)) //
//
void RI(vector< int >&a, int n){a.resize(n); for ( int i=0;i<n;i++) scanf ( "%d" ,&a[i]);} //
void RI(){} void RI( int &X){ scanf ( "%d" ,&X);} template < typename ...R> //
void RI( int &f,R&...r){RI(f);RI(r...);} void RI( int *p, int *q){ int d=p<q?1:-1; //
while (p!=q){ scanf ( "%d" ,p);p+=d;}} void print(){cout<<endl;} template < typename T> //
void print( const T t){cout<<t<<endl;} template < typename F, typename ...R> //
void print( const F f, const R...r){cout<<f<< ", " ;print(r...);} template < typename T> //
void print(T*p, T*q){ int d=p<q?1:-1; while (p!=q){cout<<*p<< ", " ;p+=d;}cout<<endl;} //
//
typedef pair< int , int > pii; //
typedef long long ll; //
typedef unsigned long long ull; //
//
template < typename T> bool umax(T&a, const T&b){ return b>a? false :(a=b, true );} //
template < typename T> bool umin(T&a, const T&b){ return b<a? false :(a=b, true );} //
template < typename T> //
void V2A(T a[], const vector<T>&b){ for ( int i=0;i<b.size();i++)a[i]=b[i];} //
template < typename T> //
void A2V(vector<T>&a, const T b[]){ for ( int i=0;i<a.size();i++)a[i]=b[i];} //
//
/* -------------------------------------------------------------------------------- */
struct Dinic {
private :
const static int maxn = 800 + 7;
struct Edge {
int from, to, cap;
Edge( int u, int v, int w): from(u), to(v), cap(w) {}
};
int s, t;
vector<Edge> edges;
vector< int > G[maxn];
bool vis[maxn];
int d[maxn], cur[maxn];
bool bfs() {
memset (vis, 0, sizeof (vis));
queue< int > Q;
Q.push(s);
d[s] = 0;
vis[s] = true ;
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for ( int i = 0; i < G[x].size(); i ++) {
Edge &e = edges[G[x][i]];
if (!vis[e.to] && e.cap) {
vis[e.to] = true ;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
int dfs( int x, int a) {
if (x == t || a == 0) return a;
int flow = 0, f;
for ( int &i = cur[x]; i < G[x].size(); i ++) {
Edge &e = edges[G[x][i]];
if (d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap))) > 0) {
e.cap -= f;
edges[G[x][i] ^ 1].cap += f;
flow += f;
a -= f;
if (a == 0) break ;
}
}
return flow;
}
public :
void clear() {
for ( int i = 0; i < maxn; i ++) G[i].clear();
edges.clear();
memset (d, 0, sizeof (d));
}
void add( int from, int to, int cap) {
edges.push_back(Edge(from, to, cap));
edges.push_back(Edge(to, from, 0));
int m = edges.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
}
int solve( int s, int t) {
this ->s = s; this ->t = t;
int flow = 0;
while (bfs()) {
memset (cur, 0, sizeof (cur));
flow += dfs(s, 1e9);
}
return flow;
}
bool FC( int fa, int rt) {
vis[rt] = true ;
int sz = G[rt].size();
for ( int i = 0; i < sz; i ++) {
Edge &e = edges[G[rt][i]];
if (e.to != fa && e.cap) {
if (vis[e.to]) return true ;
if (FC(rt, e.to)) return true ;
}
}
vis[rt] = false ;
return false ;
}
bool get( int n, int m) {
memset (vis, 0, sizeof (vis));
for ( int i = 1; i <= n; i ++) {
if (FC(-1, i)) return true ;
}
return false ;
}
void out( int n, int m) {
int now = n * 2 + m * 2 + 1;
for ( int i = 0; i < n; i ++) {
for ( int j = 0; j < m; j ++) {
printf ( "%d%c" , edges[now].cap, j == m - 1? ‘\n‘ : ‘ ‘ );
now += 2;
}
}
}
};
Dinic solver;
const int maxn = 407;
int row[maxn], col[maxn];
int main() {
#ifndef ONLINE_JUDGE
freopen ( "in.txt" , "r" , stdin);
#endif // ONLINE_JUDGE
int n, m, k;
while (cin >> n >> m >> k) {
solver.clear();
int total = 0;
for ( int i = 1; i <= n; i ++) {
int x;
RI(x);
solver.add(0, i, x);
total += x;
}
for ( int i = 1; i <= m; i ++) {
int x;
RI(x);
solver.add(n + i, n + m + 1, x);
}
for ( int i = 1; i <= n; i ++) {
for ( int j = 1; j <= m; j ++) {
solver.add(i, n + j, k);
}
}
int flow = solver.solve(0, n + m + 1);
if (flow != total) puts ( "Impossible" );
else {
if (solver.get(n, m)) puts ( "Not Unique" );
else {
puts ( "Unique" );
solver.out(n, m);
}
}
}
return 0; //
} //
//
//
//
/* ******************************************************************************** */
|