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 (Java/Others)
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.
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.
4 2
4 2
4 2 2
2 2 5 0
5 4
1 4 3
9
1 2 3 3
Impossible
Unique
1 2 3 3
| 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)的更多相关文章
- HDU4888 Redraw Beautiful Drawings(最大流唯一性判定:残量网络删边判环)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4888 Description Alice and Bob are playing toget ...
- HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
题意:给定n*m个格子,每个格子能填0-k 的整数.然后给出每列之和和每行之和,问有没有解,有的话是不是唯一解,是唯一解输出方案. 思路:网络流,一共 n+m+2个点 源点 到行连流量为 所给的 ...
- hdu4888 Redraw Beautiful Drawings(最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4888 题意:给一个矩阵没行的和和每列的和,问能否还原矩阵,如果可以还原解是否唯一,若唯一输出该矩阵. ...
- hdu4888 Redraw Beautiful Drawings 最大流+判环
hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/6553 ...
- Redraw Beautiful Drawings(hdu4888)网络流+最大流
Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/O ...
- HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...
- hdu4888 Redraw Beautiful Drawings
14更多学校的第二个问题 网络流量 分别以行,列作为结点建图 i行表示的结点到j列表示的结点的流量便是(i, j)的值 跑遍最大流 若满流了便是有解 推断是否unique 就是在残余网络 ...
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- HDU Redraw Beautiful Drawings 推断最大流是否唯一解
点击打开链接 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 ...
随机推荐
- linux xampp常见问题
一.常见问题 1.安装xampp4linux后,只能本机(http://localhost)访问,局域网内其他机器无法访问 解答:在/opt/lampp/etc中修改httpd.conf,将Liste ...
- 3243: [Noi2013]向量内积 - BZOJ
Description 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知 ...
- Netty4.x中文教程系列(四) 对象传输
Netty4.x中文教程系列(四) 对象传输 我们在使用netty的过程中肯定会遇到传输对象的情况,Netty4通过ObjectEncoder和ObjectDecoder来支持. 首先我们定义一个U ...
- c++ 常用数据接口 set
#include <set> #include <iostream> #include <string> int main(void) { std::set< ...
- 为什么数据可以从pl/sql查出来而使用ado.net查询,结果却是空?
1.背景 一条记录(如select * from A where a='1'),使用pl/sql作为条件可以查询出记录,但用ado.net sql查询结果却是空. 2.原因 a字段的数据类型的char ...
- 平常写css网页制作时最实用的九条CSS技巧
一.使用css缩写 使用缩写可以帮助减少你CSS文件的大小,更加容易阅读.css缩写的主要规则请参看<css基本语法>. 二.明确定义单位,除非值为0 忘记定义尺寸的单位是CSS新手普遍的 ...
- 【块状树】BZOJ 1086: [SCOI2005]王室联邦
1086: [SCOI2005]王室联邦 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 826 Solved: ...
- PHP读取xml方法讲解
一,什么是xml,xml有什么用途 XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Marku ...
- HTML中动态图片切换JQuery实现
相信很多同学都注意到了,各大新闻或者娱乐网站都含有动态图片切换,那个漂亮的感觉让刚刚学习html的人,都非常好奇和心动.那下面就让我们看一下到底如何实现动态图片切换呢?看一下百度贴吧的效果图吧~ // ...
- Java学习第二篇:类,对象,成员属性,成员方法,构造方法,类变量,类方法
一.类的定义 一个全面的类定义是比较复杂的, 定义如下: