HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
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.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <numeric>
using namespace std;
typedef long long LL; const int MAXN = ;
const int MAXV = MAXN << ;
const int MAXE = * MAXN * MAXN;
const int INF = 0x3f3f3f3f; struct ISAP {
int head[MAXV], cur[MAXV], gap[MAXV], dis[MAXV], pre[MAXV];
int to[MAXE], next[MAXE], flow[MAXE];
int n, ecnt, st, ed; void init(int n) {
this->n = n;
memset(head + , -, n * sizeof(int));
ecnt = ;
} void add_edge(int u, int v, int c) {
to[ecnt] = v; flow[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
} void bfs() {
memset(dis + , 0x3f, n * sizeof(int));
queue<int> que; que.push(ed);
dis[ed] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
gap[dis[u]]++;
for(int p = head[u]; ~p; p = next[p]) {
int v = to[p];
if(flow[p ^ ] && dis[u] + < dis[v]) {
dis[v] = dis[u] + ;
que.push(v);
}
}
}
} int max_flow(int ss, int tt) {
st = ss, ed = tt;
int ans = , minFlow = INF;
for(int i = ; i <= n; ++i) {
cur[i] = head[i];
gap[i] = ;
}
bfs();
int u = pre[st] = st;
while(dis[st] < n) {
bool flag = false;
for(int &p = cur[u]; ~p; p = next[p]) {
int v = to[p];
if(flow[p] && dis[u] == dis[v] + ) {
flag = true;
minFlow = min(minFlow, flow[p]);
pre[v] = u;
u = v;
if(u == ed) {
ans += minFlow;
while(u != st) {
u = pre[u];
flow[cur[u]] -= minFlow;
flow[cur[u] ^ ] += minFlow;
}
minFlow = INF;
}
break;
}
}
if(flag) continue;
int minDis = n - ;
for(int p = head[u]; ~p; p = next[p]) {
int &v = to[p];
if(flow[p] && dis[v] < minDis) {
minDis = dis[v];
cur[u] = p;
}
}
if(--gap[dis[u]] == ) break;
++gap[dis[u] = minDis + ];
u = pre[u];
}
return ans;
} int stk[MAXV], top;
bool sccno[MAXV], vis[MAXV]; bool dfs(int u, int f, bool flag) {
vis[u] = true;
stk[top++] = u;
for(int p = head[u]; ~p; p = next[p]) if(flow[p]) {
int v = to[p];
if(v == f) continue;
if(!vis[v]) {
if(dfs(v, u, flow[p ^ ])) return true;
} else if(!sccno[v]) return true;
}
if(!flag) {
while(true) {
int x = stk[--top];
sccno[x] = true;
if(x == u) break;
}
}
return false;
} bool acycle() {
memset(sccno + , , n * sizeof(bool));
memset(vis + , , n * sizeof(bool));
top = ;
return dfs(ed, , );
}
} G; int row[MAXN], col[MAXN];
int mat[MAXN][MAXN];
int n, m, k, ss, tt; void solve() {
int sumr = accumulate(row + , row + n + , );
int sumc = accumulate(col + , col + m + , );
if(sumr != sumc) {
puts("Impossible");
return ;
}
int res = G.max_flow(ss, tt);
if(res != sumc) {
puts("Impossible");
return ;
}
if(G.acycle()) {
puts("Not Unique");
} else {
puts("Unique");
for(int i = ; i <= n; ++i) {
for(int j = ; j < m; ++j) printf("%d ", G.flow[mat[i][j]]);
printf("%d\n", G.flow[mat[i][m]]);
}
}
} int main() {
while(scanf("%d%d%d", &n, &m, &k) != EOF) {
for(int i = ; i <= n; ++i) scanf("%d", &row[i]);
for(int i = ; i <= m; ++i) scanf("%d", &col[i]);
ss = n + m + , tt = n + m + ;
G.init(tt);
for(int i = ; i <= n; ++i) G.add_edge(ss, i, row[i]);
for(int i = ; i <= m; ++i) G.add_edge(n + i, tt, col[i]);
for(int i = ; i <= n; ++i) {
for(int j = ; j <= m; ++j) {
mat[i][j] = G.ecnt ^ ;
G.add_edge(i, n + j, k);
}
}
solve();
}
}
HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)的更多相关文章
- hdu 4888 Redraw Beautiful Drawings(最大流,判环)
pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888 加入一个源点与汇点,建图例如以下: 1. 源点 -> 每一行相应 ...
- hdu 4888 Redraw Beautiful Drawings 最大流
好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...
- hdu 4888 Redraw Beautiful Drawings 网络流
题目链接 一个n*m的方格, 里面有<=k的数, 给出每一行所有数的和, 每一列所有数的和, 问你能否还原这个图, 如果能, 是否唯一, 如果唯一, 输出还原后的图. 首先对行列建边, 源点向行 ...
- HDU 4888 Redraw Beautiful Drawings
网络流. $s$向每一个$r[i]$连边,容量为$r[i]$. 每一个$r[i]$向每一个$c[j]$连边,容量为$k$. 每一个$c[j]$向$t$连边容量为$c[j]$. 跑最大流,中间每一条边上 ...
- HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
题意:给定n*m个格子,每个格子能填0-k 的整数.然后给出每列之和和每行之和,问有没有解,有的话是不是唯一解,是唯一解输出方案. 思路:网络流,一共 n+m+2个点 源点 到行连流量为 所给的 ...
- HDU 4888 Redraw Beautiful Drawings 网络流 建图
题意: 给定n, m, k 以下n个整数 a[n] 以下m个整数 b[n] 用数字[0,k]构造一个n*m的矩阵 若有唯一解则输出这个矩阵.若有多解输出Not Unique,若无解输出Impossib ...
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- hdu4888 Redraw Beautiful Drawings 最大流+判环
hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/6553 ...
- HDU Redraw Beautiful Drawings 推断最大流是否唯一解
点击打开链接 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 ...
随机推荐
- 如何在html中插入视频
如何在html中插入视频 1,插入优酷视频: 在优酷分享界面有个html代码,直接复制放入body中,定义div的align居中即可 2.插入本地视频:用video属性 用mp4格式 <vid ...
- This application failed to start because it could not find or load the Qt platform plugin "xcb".
1. copy libQt5DBus.so.5 2. add QT_PLUGIN_PATH blog.csdn.net/windows_nt/article/details/242 ...
- 查看Sql Server所有表占用的空间大小
2010-01-26 sp_spaceused可以查看某个表占用的空间,但不能一次查看所有的表.今天研究了一下这个sp,写了下面这个查询: --刷新系统数据dbcc updateusage(0) wi ...
- 【Android测试】【第七节】Monkey——源码浅谈
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4713466.html 前言 根据上一篇我们学会了Monke ...
- Linux CentOS 编绎安装Python 3.5
Linux CentOS 编绎安装Python 3.5 先决条件(若无安装,则不能编绎使用idle3):yum install tk-devel xz -d Python-3.5.0.tar.xzta ...
- 从输入url到页面加载完成都发生了什么?
原文地址: http://segmentfault.com/a/1190000003925803 根据 URL 请求页面过程 过程概述 浏览器查找域名对应的 IP 地址: 浏览器根据 IP 地址与服务 ...
- C/C++程序编译流程(预处理->编译->汇编->链接)
程序的基本流程如图: 1. 预处理 预处理相当于根据预处理指令组装新的C/C++程序.经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内 ...
- 通过自定义属性存储数据实现输入框获得焦点与失去焦点改变value值
http://gopro.ee.cagoe.com/index.html html: <div class="name"><input value=&qu ...
- ArcGIS API for Silverlight 调用GP服务绘制等值面
原文:ArcGIS API for Silverlight 调用GP服务绘制等值面 GP服务模型如下图: 示例效果图片如下:
- CentOS 6.3下PostgreSQL 的安装与配置
一.简介 PostgreSQL 是一种非常复杂的对象-关系型数据库管理系统(ORDBMS),也是目前功能最强大,特性最丰富和最复杂的自由软件数据库系统.有些特性甚至连商业数据库都不具备.这个起源于伯克 ...