题意:题目有点长,但其实很简单的,就是给你一个N值,代表有一个N*N的整数矩阵,然后给出每一行的和值,
      再给出每一列的和值,问是否存在这样的矩阵,是则输出YES,并输出这个矩阵,否则输出NO,若答案不
      唯一则输出一个答案即可。

解题思路:网络流的建图题,多加两个点分别为源点与汇点,源点与代表各行的点相连,容量为行和;
          代表各列的点与汇点相连,容量为列和;
          行与每一个列都连一条边,容量为100,每一条边对应一个矩阵中的元素。
   对上图求最大流,若最大流的值为所有列和或所有行和的值则存在,并根据边标号读出矩阵中的元素,
   否则不存在。(注意:建图注意方向,边标号要记清楚,每建一条边,边标号都会加两次,一次是存
   边,一次是存反向边)。

31msC++代码
#include <stdio.h>
#include <iostream>
#include <string.h>
#define VM 100010
#define EM 400010

using namespace std;
const int inf = 0x3f3f3f3f;

struct E
{
    int to, frm, nxt, cap;
}edge[EM];

int head[VM], e;//建图时初始化
int dep[VM], gap[VM];//ISAP函数内初始化

void init()
{
 e = 0;
 memset(head, -1, sizeof(head));
}

int addEdge(int cu, int cv, int cw)
{
    edge[e].frm = cu;
    edge[e].to = cv;
    edge[e].cap = cw;
    edge[e].nxt = head[cu];
    head[cu] = e++;

    edge[e].frm = cv;
    edge[e].to = cu;
    edge[e].cap = 0;
    edge[e].nxt = head[cv];
    head[cv] = e++;
    return (e - 1);
}

int que[VM];

void BFS(int des)
{
    memset(dep, -1, sizeof(dep));
    memset(gap, 0, sizeof(gap));
    gap[0] = 1;
    int front = 0, rear = 0;
    dep[des] = 0;
    que[rear++] = des;
    int u, v;
    while (front != rear)
    {
        u = que[front++];
        front = front%VM;
        for (int i=head[u]; i!=-1; i=edge[i].nxt)
        {
            v = edge[i].to;
            if (edge[i].cap != 0 || dep[v] != -1)
                continue;
            que[rear++] = v;
            rear = rear % VM;
            ++gap[dep[v] = dep[u] + 1];
        }
    }
}

int cur[VM], stack[VM];
//sap模板
int ISAP(int src, int des, int n)//源点、汇点、图中点的总数
{
    int res = 0;
    BFS(des);
    int top = 0;
    memcpy(cur, head, sizeof(head));
    int u = src, i;
    while (dep[src] < n)
    {
        if (u == des)
        {
            int temp = inf, inser = n;
            for (i=0; i!=top; ++i)
                if (temp > edge[stack[i]].cap)
                {
                    temp = edge[stack[i]].cap;
                    inser = i;
                }
            for (i=0; i!=top; ++i)
            {
                edge[stack[i]].cap -= temp;
                edge[stack[i]^1].cap += temp;
            }
            res += temp;
            top = inser;
            u = edge[stack[top]].frm;
        }

        if (u != des && gap[dep[u] -1] == 0)
            break;
        for (i = cur[u]; i != -1; i = edge[i].nxt)
            if (edge[i].cap != 0 && dep[u] == dep[edge[i].to] + 1)
                break;

        if (i != -1)
        {
            cur[u] = i;
            stack[top++] = i;
            u = edge[i].to;
        }
        else
        {
            int min = n;
            for (i = head[u]; i != -1; i = edge[i].nxt)
            {
                if (edge[i].cap == 0)
                    continue;
                if (min > dep[edge[i].to])
                {
                    min = dep[edge[i].to];
                    cur[u] = i;
                }
            }
            --gap[dep[u]];
            ++gap[dep[u] = min + 1];
            if (u != src)
                u = edge[stack[--top]].frm;
        }
    }
    return res;
}

int main()
{
    int N,i,j,sumr,sumc,c;
    while(scanf("%d", &N) != EOF)
    {
        sumr =sumc = 0;
        init();
        for(i = 1; i <= N; i++)
        {
            scanf("%d",&c);
            addEdge(1,1+i,c);
            sumr += c;
        }
        for(i = 1; i <= N; i++)
        {
            for(j = 1; j <= N; j++)
                addEdge(1+i,1+N+j,100);
        }
        for(i = 1; i <= N; i++)
        {
            scanf("%d",&c);
            addEdge(1+N+i,1+N+N+1,c);
            sumc += c;
        }
        int ans = ISAP(1,1+N+N+1,1+N+N+1);
        if(sumc != sumr || ans != sumr)
            printf("NO\n");
        else
        {
            printf("YES\n");
            for(i = 0; i < N; i++)
            {
                for(j = 0; j < N; j++)
                {
                    if(j == N-1)
                        printf("%d",100 - edge[i*2*N+2*j+2*N].cap);
                    else
                        printf("%d ",100 - edge[i*2*N+2*j+2*N].cap);
                }
                printf("\n");
            }
        }

    }

    return 0;
}