Redraw Beautiful Drawings

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1660    Accepted Submission(s): 357

Problem Description
Alice and Bob are playing together. Alice is crazy about art and she has visited many museums around the world. She has a good memory and she can remember all drawings she has seen.



Today Alice designs a game using these drawings in her memory. First, she matches K+1 colors appears in the picture to K+1 different integers(from 0 to K). After that, she slices the drawing into grids and there are N rows and M columns. Each grid has an integer
on it(from 0 to K) representing the color on the corresponding position in the original drawing. Alice wants to share the wonderful drawings with Bob and she tells Bob the size of the drawing, the number of different colors, and the sum of integers on each
row and each column. Bob has to redraw the drawing with Alice's information. Unfortunately, somtimes, the information Alice offers is wrong because of Alice's poor math. And sometimes, Bob can work out multiple different drawings using the information Alice
provides. Bob gets confused and he needs your help. You have to tell Bob if Alice's information is right and if her information is right you should also tell Bob whether he can get a unique drawing.
 
Input
The input contains mutiple testcases.



For each testcase, the first line contains three integers N(1 ≤ N ≤ 400) , M(1 ≤ M ≤ 400) and K(1 ≤ K ≤ 40).

N integers are given in the second line representing the sum of N rows.

M integers are given in the third line representing the sum of M columns.



The input is terminated by EOF.
 
Output
For each testcase, if there is no solution for Bob, output "Impossible" in one line(without the quotation mark); if there is only one solution for Bob, output "Unique" in one line(without the quotation mark) and output an N * M matrix in the following N lines
representing Bob's unique solution; if there are many ways for Bob to redraw the drawing, output "Not Unique" in one line(without the quotation mark).
 
Sample Input
2 2 4
4 2
4 2
4 2 2
2 2 5 0
5 4
1 4 3
9
1 2 3 3
 
Sample Output
Not Unique
Impossible
Unique
1 2 3 3
 
Author
Fudan University
 

给你一个n*m的矩阵,然后个格子里面有一个小于k的数,而且告诉你每行和每列的和,让你求是否存在解,并推断是否唯一。

建图:源点和每行连边,容量为每行的和。每列和汇点连边,容量为每列的和。每行和每列连边,容量为k。
推断是否存在唯一解,在残留网络里面是否能找到一个环。
//515MS	7304K
#include<stdio.h>
#include<string.h>
#define M 1007
int s,t,n,m,k,sum1,sum2;
int row[M],col[M],vis[M],g[M][M];
const int MAXN=20010;//点数的最大值
const int MAXM=880010;//边数的最大值
const int INF=0x3f3f3f3f;
struct Node
{
int from,to,next;
int cap;
}edge[MAXM];
int tol;
int head[MAXN];
int dis[MAXN];
int gap[MAXN];//gap[x]=y :说明残留网络中dis[i]==x的个数为y
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
edge[tol].from=u;
edge[tol].to=v;
edge[tol].cap=w;
edge[tol].next=head[u];
head[u]=tol++;
edge[tol].from=v;
edge[tol].to=u;
edge[tol].cap=0;
edge[tol].next=head[v];
head[v]=tol++;
}
void BFS(int start,int end)
{
memset(dis,-1,sizeof(dis));
memset(gap,0,sizeof(gap));
gap[0]=1;
int que[MAXN];
int front,rear;
front=rear=0;
dis[end]=0;
que[rear++]=end;
while(front!=rear)
{
int u=que[front++];
if(front==MAXN)front=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]!=-1)continue;
que[rear++]=v;
if(rear==MAXN)rear=0;
dis[v]=dis[u]+1;
++gap[dis[v]];
}
}
}
int SAP(int start,int end)
{
int res=0,nn=end+1;
BFS(start,end);
int cur[MAXN];
int S[MAXN];
int top=0;
memcpy(cur,head,sizeof(head));
int u=start;
int i;
while(dis[start]<nn)
{
if(u==end)
{
int temp=INF;
int inser;
for(i=0;i<top;i++)
if(temp>edge[S[i]].cap)
{
temp=edge[S[i]].cap;
inser=i;
}
for(i=0;i<top;i++)
{
edge[S[i]].cap-=temp;
edge[S[i]^1].cap+=temp;
}
res+=temp;
top=inser;
u=edge[S[top]].from;
}
if(u!=end&&gap[dis[u]-1]==0)//出现断层,无增广路
break;
for(i=cur[u];i!=-1;i=edge[i].next)
if(edge[i].cap!=0&&dis[u]==dis[edge[i].to]+1)
break;
if(i!=-1)
{
cur[u]=i;
S[top++]=i;
u=edge[i].to;
}
else
{
int min=nn;
for(i=head[u];i!=-1;i=edge[i].next)
{
if(edge[i].cap==0)continue;
if(min>dis[edge[i].to])
{
min=dis[edge[i].to];
cur[u]=i;
}
}
--gap[dis[u]];
dis[u]=min+1;
++gap[dis[u]];
if(u!=start)u=edge[S[--top]].from;
}
}
return res;
} void build()
{
sum1=0,sum2=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&row[i]);
sum1+=row[i];
addedge(s,i,row[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d",&col[i]);
sum2+=col[i];
addedge(n+i,t,col[i]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
addedge(i,n+j,k);
} bool iscycle(int u,int fa)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
if(i==(fa^1))continue;
if(edge[i].cap)
{
if(vis[edge[i].to])return true;
vis[edge[i].to]=true;
if(iscycle(edge[i].to,i))return true;
vis[edge[i].to]=false;
}
}
return false;
}
void solve()
{
if(sum1!=sum2){printf("Impossible\n");return;}
int anss=SAP(s,t);
//printf("anss=%d\n",anss);
if(anss!=sum1){printf("Impossible\n");return;}
memset(vis,false,sizeof(vis));
int flag=0;
for(int i=1;i<=n;i++)//推断残留网络是否存在环
if(iscycle(i,-1))
{flag=1;break;}
if(flag)printf("Not Unique\n");
else
{
printf("Unique\n");
for(int u=1;u<=n;u++)
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v>n&&v<=n+m)
g[u][v-n]=k-edge[i].cap;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++)
printf("%d ",g[i][j]);
printf("%d\n",g[i][m]);
}
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
s=0,t=n+m+1;
init();
build();
solve();
}
}

HDU Redraw Beautiful Drawings 推断最大流是否唯一解的更多相关文章

  1. HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)

    Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...

  2. HDU4888 Redraw Beautiful Drawings(最大流唯一性判定:残量网络删边判环)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4888 Description Alice and Bob are playing toget ...

  3. hdu4888 Redraw Beautiful Drawings(最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4888 题意:给一个矩阵没行的和和每列的和,问能否还原矩阵,如果可以还原解是否唯一,若唯一输出该矩阵. ...

  4. 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

    传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...

  5. Redraw Beautiful Drawings(hdu4888)网络流+最大流

    Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/O ...

  6. hdu4888 Redraw Beautiful Drawings 最大流+判环

    hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/6553 ...

  7. HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)

    Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. hdu 4888 Redraw Beautiful Drawings(最大流,判环)

    pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888 加入一个源点与汇点,建图例如以下: 1. 源点 -> 每一行相应 ...

  9. hdu 4888 Redraw Beautiful Drawings 最大流

    好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...

随机推荐

  1. windows-install-python-and-sphinx(*.rst file)

    http://sphinx-doc.org/install.html#windows-install-python-and-sphinx

  2. StackExchange.Redis 使用

    StackExchange.Redis 使用 - 事件(五) 摘要: ConnectionMultiplexer 可以注册如下事件ConfigurationChanged- 配置更改时Configur ...

  3. 移动端 transition动画函数的封装(仿Zepto)以及 requestAnimationFrame动画函数封装(仿jQuery)

    移动端 css3 transition 动画 ,requestAnimationFrame 动画  对于性能的要求,h5优先考虑: 移动端 单页有时候 制作只用到简单的css3动画即可,我们封装一下, ...

  4. 国内Android应用推广的六大主流方式

    国内Android应用推广的六大主流方式 http://mobi.baike.com/article-19433.html 随着Android市场份额的飞速增长,越来越多的国内开发团队和公司開始投入A ...

  5. WPF学习(9)样式和行为

    在asp.net世界中,我们的美工人员会为我们准备好静态页面,它注意包括三个部分:html.css和js.而在WPF世界里,也同样有着类似这三个部分的静态页面:Xaml.Style和Behaviors ...

  6. Youtube最佳Red5 官方视频下载指南,字幕【亲测成功】

    前言 最近在研究Red5 流媒体服务框架,官网上的信息足以让一个新手入门 有官方參考手冊 -- 高速了解red5的相关信息 有Red5 on Stackoverflow  -- 在上面能够提问或者回答 ...

  7. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  8. ORACLE在表中添加的目光凝视和读取列

    在ORACLE中给表.列添加凝视以及读取凝视 1.给表填加凝视:SQL>comment on table 表名 is '表凝视"; 2.给列加凝视:SQL>comment on ...

  9. ubuntu 14.04 安装搜狗拼音输入法

    原文:ubuntu 14.04 安装搜狗拼音输入法 ubuntu桌面系统下终于有了好用的拼音法-搜狗拼音输入法,欲在ubuntu 14.04下安装搜狗拼音输入法相当的简单. 先到搜狗拼音官网下载对应的 ...

  10. Android监视返回键

    android在发展中,监视键返回到后事件经常被用来,在下面的例子来说明什么android返回键事件监听器. public class BackKeyTest extends Activity { / ...