HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)
题意:给定n*m个格子,每个格子能填0-k 的整数。然后给出每列之和和每行之和,问有没有解,有的话是不是唯一解,是唯一解输出方案。
思路:网络流,一共 n+m+2个点 源点 到行连流量为 所给的 当前行之和。 每行 连到每一列 一条流量为 k的边,每列到汇点连 列和。如果流量等于总和则有解,反之无解(如果列总和不等于行总和也无解)。 判断方案是否唯一 找残留网络是否存在长度大于2的环即可,有环说明不唯一。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include <iostream>
#include<climits>
using namespace std;
const int N = ;
const int M = ;
int n;
int ecnt, head[N], nx[M], to[M], va[M], cur_edge[N];
int source, target, flow, pre[N], lev[N], qu[N], sign;
void addedge(int u, int v, int w) {
to[ecnt] = v;
nx[ecnt] = head[u];
va[ecnt] = w;
head[u] = ecnt++;
}
bool bfs(int s, int t) {
std::fill(lev, lev + n, -);
sign = t;
lev[t] = ;
int st = , ed = ;
qu[ed++] = t;
while (st != ed && lev[s] == -) {
int u = qu[st++];
for (int i = head[u]; i != -; i = nx[i]) {
if (va[i ^ ] > && lev[to[i]] == -) {
lev[to[i]] = lev[u] + ;
qu[ed++] = to[i];
}
}
}
return lev[s] != -;
}
void push() {
int delta = INT_MAX, u, p;
for (u = target; u != source; u = to[p ^ ]) {
p = pre[u];
delta = std::min(delta, va[p]);
}
for (u = target; u != source; u = to[p ^ ]) {
p = pre[u];
va[p] -= delta;
if (!va[p]) {//注意double时要改
sign = to[p ^ ];
}
va[p ^ ] += delta;
}
flow += delta;
}
void dfs(int u) {
if (u == target)
push();
else {
for (int i = cur_edge[u]; i != -; i = nx[i]) {
if (va[i] > && lev[u] == lev[to[i]] + ) {
pre[to[i]] = i;
dfs(to[i]);
if (lev[sign] > lev[u]) {
return;
}
sign = target;
}
}
lev[u] = -;
}
}
void dinic(int s, int t, int node_cnt) {
source = s;
target = t;
n = node_cnt; //construct graph flow = ;
while (bfs(source, target)) {
for (int i = ; i < n; ++i) {
cur_edge[i] = head[i];
}
dfs(source);
} }
int nc, kc, mc, sum1, sum2;
int r[], c[];
void init() {
sum1 = sum2 = ;
for (int i = ; i < nc; ++i) {
scanf("%d", &r[i]);
sum1 += r[i];
}
for (int i = ; i < mc; ++i) {
scanf("%d", &c[i]);
sum2 += c[i];
}
}
int flag = ;
bool bo[];
bool bb[];
int cas[];
int ri = ;
void gao(int now, int fa) {//找环
if(flag)return;
//printf("->%d ",now);
bo[now] = true;
for (int i = head[now]; i != -; i = nx[i]) {
int u = to[i];
if (u == fa)
continue;
if (va[i] == )
continue; // printf(" {%d %d}\n",now,u);
if (bb[u]) {
// puts("fuck");
flag = ;
return;
}
if (cas[i] == ri)
continue;
cas[i] = ri;
//if(bo[u])continue;
bb[u] = true;
gao(u, now);
bb[u] = false;
}
}
void solve() {
if (sum1 != sum2) {
puts("Impossible");
return;
}
std::fill(head, head + mc + nc + , -);
ecnt = ;
int s, t;
s = nc + mc;
t = s + ;
// printf("st:%d %d\n",s,t);
for (int i = ; i < nc; ++i) {
for (int j = ; j < mc; ++j) { // printf("[%d %d]\n",i,j+nc);
addedge(i, j + nc, kc);
addedge(j + nc, i, );
}
}
for (int i = ; i < nc; ++i) {
// printf("[%d %d]\n",s,i);
addedge(s, i, r[i]);
addedge(i, s, );
}
for (int i = ; i < mc; ++i) { // printf("[%d %d]\n",i+nc,t);
addedge(i + nc, t, c[i]);
addedge(t, i + nc, );
}
dinic(s, t, t + );
// printf("flow:%d\n",flow);
if (flow == sum1) { memset(bo, , sizeof(bo));
memset(bb, , sizeof(bb));
flag = ;
for (int i = ; i <= t; ++i) {
if(flag)break;
bb[i] = true;
gao(i, -);
bb[i] = false;
}
if (flag)
puts("Not Unique");
else {
puts("Unique");
for (int i = ; i < nc; ++i) {
for (int j = ; j < mc; ++j) {
int now = i * mc + j;
printf("%d", va[now << | ]);
if (j == mc - )
puts("");
else
printf(" ");
}
}
}
} else
puts("Impossible");
}
int main() {
memset(cas, , sizeof(cas));
while (scanf("%d%d%d", &nc, &mc, &kc) != EOF) {
++ri;
init();
solve();
}
return ;
}
HDU 4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)的更多相关文章
- 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(2014 Multi-University Training Contest 3)
Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- hdu 4888 Redraw Beautiful Drawings(最大流,判环)
pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888 加入一个源点与汇点,建图例如以下: 1. 源点 -> 每一行相应 ...
- hdu 4888 Redraw Beautiful Drawings 网络流
题目链接 一个n*m的方格, 里面有<=k的数, 给出每一行所有数的和, 每一列所有数的和, 问你能否还原这个图, 如果能, 是否唯一, 如果唯一, 输出还原后的图. 首先对行列建边, 源点向行 ...
- hdu 4888 Redraw Beautiful Drawings 最大流
好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...
- 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
网络流. $s$向每一个$r[i]$连边,容量为$r[i]$. 每一个$r[i]$向每一个$c[j]$连边,容量为$k$. 每一个$c[j]$向$t$连边容量为$c[j]$. 跑最大流,中间每一条边上 ...
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- Redraw Beautiful Drawings(hdu4888)网络流+最大流
Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/O ...
随机推荐
- 简单的php性能注意点
什么情况,可能遇到性能问题: 1.php语法使用的不恰当 2.使用php语言做了它不擅长做的事 3.用php语言连接的服务不给力 4.php自身的短板 5.我也不知道的问题 一般情况:php性能问题不 ...
- 用JS打开网页时自动更改css样式,可用于处理浏览器兼容
代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- POJ 3468(树状数组的威力)
之前说过这是线段树的裸题,但是当看了http://kenby.iteye.com/blog/962159 这篇题解后我简直震惊了,竟然能如此巧妙地转化为用树状数组来处理,附上部分截图(最好还是进入原网 ...
- MFC编程入门之前言
本系列主要偏重于理论方面的知识,目的是打好底子,练好内功,在使用VC++编程时不至于丈二和尚摸不着头脑.本系列也会涉及到VC++的原理性的东西,同样更重视实用性,学完本系列以后,基本的界面程序都能很容 ...
- double 逆序
请设计一个函数,不许用到字符串函数,用数学运算,将double类型数据转换,例如123.456转换成654.321 int _tmain(int argc, _TCHAR* argv[]) { con ...
- Android控件之Button(按钮控件)和ImageButton(图片按钮控件)
一.Button和ImageButton特证: 1.共同特证: 都可以作为一个按钮产生点击事件 2.不同特证: Button有text的属性,ImageButton没有 ImageButton有src ...
- Sqlserver_left join 、right join、 inner join 用法
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...
- 基于dubbo源码包通过Maven构建dubbo的详细步骤
通过Maven构建dubbo 既然可以下载得到源码以及发布包,那么为什么要去构建dubbo呢?,我们先来看下dubbo的主要模块: 我们不仅要使用dubbo的核心框架,还要使用它的一些服务,比如管理控 ...
- features recreate的含义
就是从数据库里导出这个features的代码块.
- iOS蓝牙4.0开发(BLE)
智能设备 和 app 通过 BLE通讯的两种模型 模型一:设备提供数据,app 展示数据: 比如小米手环 模型二:app提供数据,设备接收: 模型与corebluetooth的对应关系: 模型一:智能 ...