//n*m的矩阵
//给出n行每行的所有数之和
//给出m列中每列的所有数之和
//每个格子的数x 0 <= x <= k
//问能不能构成矩阵 , 这个矩阵是否唯一确定
//判断最大流是否唯一确定是
//在残余网络看能不能找到一个环 , 如果能找到那么最大流
//可以沿着这个环走一遍而不改变最大流
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std ;
const int maxn = 1010 ;
const int maxm = 410*410 ;
const int inf = 0x7fffffff ;
int st = 0 ; int en = 1001 ;
int vis[maxn] ;
int head[maxn] ;
int dis[maxn] ;
int q[maxn];
int nedge = 0 ;
int ma[maxn][maxn] ;
struct Edge
{
int v ;int next;
int w ;
}edge[maxm<<1] ;
void addedge(int u , int v , int w)
{
edge[nedge].v = v ;
edge[nedge].w = w ;
edge[nedge].next = head[u] ;
head[u] = nedge++ ;
edge[nedge].v = u ;
edge[nedge].w = 0 ;
edge[nedge].next = head[v] ;
head[v] = nedge++ ;
}
bool bfs()
{
memset(dis , -1 ,sizeof(dis)) ;
int front = 0 , tear = 0 ;
dis[st] = 0 ;
q[tear++] = st;
while(front < tear)
{
int u = q[front++] ;
for(int i = head[u]; i != -1 ; i = edge[i].next)
{
int v = edge[i].v ;
if(edge[i].w > 0 && dis[v] < 0)
{
dis[v] = dis[u] + 1 ;
q[tear++] = v ;
}
}
}
if(dis[en] > 0)
return true ;
return false ;
}
int dfs(int x,int mx)
{
if(x==en)
return mx;;
int ans=0;
int a;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(dis[v]==dis[x]+1&&edge[i].w>0&&(a=dfs(v,min(mx,edge[i].w))))
{
edge[i].w -= a;
edge[i^1].w += a;
ans += a;
mx -= a;
if(!mx)
break;
}
}
if(!ans)
dis[x] = -1;
return ans;
}
bool dfss(int u , int pre)
{
for(int i = head[u] ;i != -1; i = edge[i].next)
{
int v = edge[i].v ;
if(v == pre || !edge[i].w || v == st || v == en)continue ;
if(vis[v])
return true ;
vis[v] = 1;
if(dfss(v , u))
return true ;
vis[v] = 0 ;
}
return false ;
}
int main()
{
// freopen("in.txt" , "r" , stdin) ;
int n , m , k;
while(~scanf("%d%d%d" , &n , &m , &k))
{
memset(head , -1 , sizeof(head)) ;
memset(vis , 0 , sizeof(vis)) ;
nedge = 0 ;
int sum1 = 0 ;
int sum2 = 0 ;
st = 0 , en = n + m + 1 ;
for(int i = 1;i <= n;i++)
{
int t ;
scanf("%d" , &t) ;
sum1 += t ;
addedge(st , i , t) ;
for(int j = 1;j <= m;j++)
addedge(i , j + n , k) ;
}
for(int j = 1;j <= m;j++)
{
int t ;
scanf("%d" , &t) ;
sum2 += t ;
addedge(j + n , en , t) ;
}
int ans = 0 ;
int res ;
if(sum1 != sum2)
{
puts("Impossible") ;
continue ;
}
while(bfs())
while(res = dfs(st , inf))
ans += res ;
if(ans != sum1)
{
puts("Impossible") ;
continue ;
}
bool flag = false ;
for(int i = 0;i <= n;i++)
if(dfss(i , -1))
{
flag = true ;
break ;
}
if(flag)
{
puts("Not Unique") ;
continue ;
}
puts("Unique") ;
for(int i = 1;i <= n;i++)
for(int j = head[i] ; j != -1 ;j = edge[j].next)
if(edge[j].v > n && edge[j].v <= n + m)
ma[i][edge[j].v - n] = edge[j^1].w ;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
printf("%d%c" , ma[i][j] , j == m?'\n':' ') ;
}
return 0 ;
}
hdu 4888 Redraw Beautiful Drawings 最大流唯一性判断
最新推荐文章于 2019-10-04 03:07:01 发布