Redraw Beautiful Drawings

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

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
 
Source
2014-07-31 01:22:46 Accepted 4888 625MS 5244K 3493 B G++

题目大意:

  求一个矩阵,给出矩阵每行和每列的和,矩阵中数字[0,K]

  若矩阵唯一,输出Unique及矩阵

  若不唯一,输出Not Unique

  若不存在,输出impossible

解题方法:

  增加源点汇点,建立网络流,

    源点->i行 容量为行和

    i行->j列 容量为k

    j列->汇点 容量为列和

  容易得到,

    若最大流<sum,则不存在

    否则存在,

      接下来转换为判断流是否唯一的问题上,即中间的流是否唯一,即中间的流能否相互转移,从增广路径的思想上来看,只需存在一个环,则可以转换流,故存在多解。问题即判断残余网络上是否存在环。

  第一次用了下之前的dinic模板,果然省事许多,可惜判断矩阵是否唯一的dfs写超时了,折腾许久,不过也终究搞定了。

#include <cstdio>
#include <cstring>
#define N 808
#define M 640008
int d[N],be[N];
int s,t,n,m,k,z,tot,all;
bool v[N];
struct Edge{
int x,y,c,next;
}e[M*];
void add(int x, int y, int z)//需保证相反边第一个为偶数
{
e[all].x=x; e[all].y=y; e[all].c=z;
e[all].next=be[x];
be[x]=all;
all++;
e[all].x=y; e[all].y=x; e[all].c=;
e[all].next=be[y];
be[y]=all;
all++;
}
bool BFS(int s, int t)
{
memset(d,-,sizeof(d));
int head=,tail=,q[N];
q[++tail]=s;
d[s]=;
while(head<tail){
int cur=q[++head];
for(int i=be[cur]; i!=-; i=e[i].next)
if(e[i].c> && d[e[i].y]==-){
d[e[i].y]=d[cur]+;
q[++tail]=e[i].y;
}
}
return d[t]!=-;
}
int Dinic(int s, int t)//防止爆栈 用stack模拟递归
{
int ans=;
int stack[N],top;
int begin[N];
while(BFS(s,t))
{
memcpy(begin,be,sizeof(be));
int cur=s;
top=;//dfs开始 清空栈
while()
{
if(cur==t){
int minc=,mini;
for(int i=; i<top; i++)
if(minc>e[stack[i]].c)
{
minc=e[stack[i]].c;
mini=i;//以便之后回到这继续增广
}
for(int i=; i<top; i++)
{
e[stack[i]].c-=minc;
e[stack[i]^].c+=minc;//第一个二进制取反 即取相反边
}
ans+=minc;
top=mini;
cur=e[stack[mini]].x;
}
for(int i=begin[cur]; i!=-; begin[cur]=i=e[begin[cur]].next)
if(e[i].c> && d[e[i].y]==d[e[i].x]+) break;
if(begin[cur]!=-){
stack[top++]=begin[cur];
cur=e[begin[cur]].y;
}else{
if(top==) break;
d[cur]=-;//当前节点不在增广路中 删除
cur=e[stack[--top]].x;//回溯
}
}
}
return ans;
}
bool dfs(int cur, int fa)
{
if(v[cur]) return ;
v[cur]=;
for(int i=be[cur]; i!=-; i=e[i].next)
if(e[i].c> && e[i].y!=fa && dfs(e[i].y,cur))
return ;
v[cur]=;
return ;
}
bool check()
{
memset(v,,sizeof(v));
for(int i=; i<=n; i++)
if(dfs(i,-)) return ;
return ;
}
void print()
{
int ans[N];
for(int i=; i<=n; i++){
for(int j=be[i]; j!=-; j=e[j].next)
ans[e[j].y]=e[j].c;
for(int j=n+; j<=n+m; j++)
if(j!=n+m) printf("%d ",k-ans[j]); else printf("%d\n",k-ans[j]);
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
s=n+m+;
t=n+m+;
tot=;
all=;
int ans=;
memset(be,-,sizeof(be));
for(int i=; i<n; i++){
scanf("%d",&z);
add(s,++tot,z);
ans+=z;
}
for(int i=; i<m; i++){
scanf("%d",&z);
add(++tot,t,z);
}
for(int i=; i<=n; i++)
for(int j=n+; j<=n+m; j++)
add(i,j,k);
ans-=Dinic(s,t);
if(ans!=) printf("Impossible\n");
else {
if(check())
printf("Not Unique\n");
else{
printf("Unique\n");
print();
}
}
}
return ;
}

HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)的更多相关文章

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

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

  2. HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)

    题意:给定n*m个格子,每个格子能填0-k 的整数.然后给出每列之和和每行之和,问有没有解,有的话是不是唯一解,是唯一解输出方案. 思路:网络流,一共 n+m+2个点   源点 到行连流量为 所给的 ...

  3. hdu4888 Redraw Beautiful Drawings(最大流)

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

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

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

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

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

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

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

  7. hdu4888 Redraw Beautiful Drawings

    14更多学校的第二个问题 网络流量   分别以行,列作为结点建图 i行表示的结点到j列表示的结点的流量便是(i, j)的值 跑遍最大流   若满流了便是有解   推断是否unique  就是在残余网络 ...

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

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

  9. HDU Redraw Beautiful Drawings 推断最大流是否唯一解

    点击打开链接 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 ...

随机推荐

  1. OpenWrt编译到底脚本

    在办公室编译OpenWrt,费时很久,原因有两个. 一是办公室网络环境比较糟糕,经常断线不说,很多技术网站间歇性的连不上,不是撞到404就是DNS解析失败等. 二是初次编译OpenWrt时需要从网上下 ...

  2. [转载]AFX_MANAGE_STATE关于资源切换

    应用程序进程本身及其调用的每个DLL模块都具有一个全局唯一的HINSTANCE句柄,它们代表了DLL或EXE模块在进程虚拟空间中的起始地址.进程本身的模块句柄一般为0x400000,而DLL模块的缺省 ...

  3. Guava文档翻译之ListenableFuture

    ListenableFutureExplained 并发是一个困难的问题,但是使用强大而简单的抽象可以极大地简化并发问题.为了简化事情,Guava使用ListenableFuture继承了JDK的Fu ...

  4. Linux重启inotify配置max_user_watches无效被恢复默认值8192的正确修改方法

    Linux下Rsync+inotify-tools实现数据实时同步中有一个重要的配置就是设置Inotify的max_user_watches值,如果不设置,当遇到大量文件的时候就会出现出错的情况. 一 ...

  5. Appboy 基于 MongoDB 的数据密集型实践

    摘要:Appboy 正在过手机等新兴渠道尝试一种新的方法,让机构可以与顾客建立更好的关系,可以说是市场自动化产业的一个前沿探索者.在移动端探索上,该公司已经取得了一定的成功,知名产品有 iHeartM ...

  6. 转:[gevent源码分析] 深度分析gevent运行流程

    [gevent源码分析] 深度分析gevent运行流程 http://blog.csdn.net/yueguanghaidao/article/details/24281751 一直对gevent运行 ...

  7. POJ 1459 Power Network(网络最大流,dinic算法模板题)

    题意:给出n,np,nc,m,n为节点数,np为发电站数,nc为用电厂数,m为边的个数.      接下来给出m个数据(u,v)z,表示w(u,v)允许传输的最大电力为z:np个数据(u)z,表示发电 ...

  8. PHP中发送邮件的几种方法总结

    1. 使用 mail() 函数 没什么好讲的,就是使用系统自带的smtp系统来发送,一般是使用sendmail来发.这个按照各个系统不同而定.使用参考手册. 2. 使用管道的形式 昨天刚测试成功,使用 ...

  9. 【转】Android 实现“再按一次退出程序”

    From:http://blog.csdn.net/ldj299/article/details/7574365 个人觉得当用户按下后退键时,出现"再按一次退出"的提示防止误操作比 ...

  10. Makefile笔记

    一个简单的Makefile描述规则组成: TARGET...:PREREQUISITES... COMMANDS... ... target:规则的目标.通常是程序中间或者最后要生成的文件名,也可以是 ...