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 ...
随机推荐
- SlimDx绘制点图元的问题
问题:点图元在自己创建的三维环境里渲染不出来,代码如下: GMCustomVertex.PositionNormalColored wellPart = new GMCustomVertex.Posi ...
- OC类的本质,深入探讨,load方法和initialize方法
1:类的本质:类也是一种类,可以叫做类类,类对象,类类型: 2:类和对象在内存中分配问题(注意区分类的对象和类对象的概念) 类对象在内存中只有一份,且只加载一次,类对象中存放了类中定义的方法: 而成员 ...
- 原生js实现仿window10系统日历效果
舞动的灵魂版js日历,完全采用js实现,故而实现了与语言无关,jsp.asp.net php asp均可使用.无论你是开发软件,还是网站,均是不可或缺的实用代码. 该日历主要实现了获取当前时间时分秒, ...
- .net 自然排序方式
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- C#笔记1:异常
reference : http://www.cnblogs.com/luminji/archive/2010/10/20/1823536.html 本章概要: 1:为什么需要异常 2:finally ...
- VIM配置(转载)
注: 转载于http://www.cnblogs.com/ma6174/ 花了很长时间整理的,感觉用起来很方便,共享一下. 我的vim配置主要有以下优点: 1.按F5可以直接编译并执行C.C++.ja ...
- NHibernate 基础
install-package nhibernate install-package nunit Customer.cs public class Customer { public virtual ...
- xargs 加 gm批量转换图片
%x50% @ ../-\ 南澳西涌_50%/@ 看了很多说明上都在用-i,这是一个已经废弃了的参数
- Lua 代码编写技巧
1.克隆表 u = {unpack(table)} 一般克隆长度较小的表 2.判断表是否为空 if next(t) == nil then.. 判断该表是否为空,包括t={}的情况 3.插入表 使用 ...
- 空格的URL编码
Q: 为什么我看的教材一会说是“+” 一会说是“%20” A: urlencode(" ") '返回+encodeURI(" ") '返回%20是有区别的