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. 在ASP.NET MVC应用程序中实现Server.Transfer()类似的功能

    在ASP.NET MVC应用程序中,如果使用Server.Transfer()方法希望将请求转发到其它路径或者Http处理程序进行处理,都会引发“为xxx执行子请求时出错”的HttpException ...

  2. dbutils报错:com.microsoft.sqlserver.jdbc.SQLServerException: 无法识别元数据的表

    今天用dbutils操作数据库,莫名地报错:com.microsoft.sqlserver.jdbc.SQLServerException: 无法识别元数据的表 检查了sql语句没有问题.经过仔细排查 ...

  3. Sublime text 取消记住上一次打开的,这功能太墨迹了!

    比较恨,这sublime text的配置全部都是配置文件. 选择菜单:Preferences->Settings-User,增加配置项 //热退出,其实实现一种模拟没有退出的状态,当程序再次启动 ...

  4. oracle——merge

      一.概述 使用merge声明从一个或者更多个表或视图中筛选记录,以用来更新或者插入到一个表或视图中.你可以指定条件以决定是执行update操作还是insert操作到目标表或视图中. 这个声明是一个 ...

  5. spring mvc 注解 annot失效

    如果带上事务,那么用annotation方式的事务注解和bean配置,事务会失效,要将service bean配置到xml文件中才行 这个问题是由于问答上有解决方案 引用 这个问题很经典了 在主容器中 ...

  6. Asp.net MVC 自定义路由在IIS7以上,提示Page Not Found 解决方法

    受限确保自定义路由在开发服务器上Ok! 然后在web.config的<webserver>节点下增加如下配置就好了.   1: <system.webServer> 2: &l ...

  7. Selenium如何使用自定义的Firefox配置文件?

    一.自动保存文件 import os from selenium import webdriver fp = webdriver.FirefoxProfile() fp.set_preference( ...

  8. Hadoop格式化HDFS报错java.net.UnknownHostException: localhost.localdomain: localhost.localdomain

    异常描述: 在对HDFS格式化,执行hadoop namenode -format命令时,出现未知的主机名的问题,异常信息如下所示: [shirdrn@localhost bin]$ hadoop n ...

  9. lintcode: 三数之和II

    题目 三数之和 II 给一个包含n个整数的数组S, 找到和与给定整数target最接近的三元组,返回这三个数的和. 样例 例如S = .  和最接近1的三元组是 -1 + 2 + 1 = 2. 注意 ...

  10. 【mysql的编程专题④】存储过程

    类似函数,但是没有返回值,把sql进行封装,便于多次使用或多种应用程序共享使用.不能用在SQL语句中,只能使用CALL调用; 创建存储过程 语法 CREATE PROCEDURE sp_name ([ ...