题意:给定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)的更多相关文章

  1. HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)

    Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...

  2. 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 ...

  3. hdu 4888 Redraw Beautiful Drawings(最大流,判环)

    pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888 加入一个源点与汇点,建图例如以下: 1. 源点 -> 每一行相应 ...

  4. hdu 4888 Redraw Beautiful Drawings 网络流

    题目链接 一个n*m的方格, 里面有<=k的数, 给出每一行所有数的和, 每一列所有数的和, 问你能否还原这个图, 如果能, 是否唯一, 如果唯一, 输出还原后的图. 首先对行列建边, 源点向行 ...

  5. hdu 4888 Redraw Beautiful Drawings 最大流

    好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...

  6. HDU 4888 Redraw Beautiful Drawings 网络流 建图

    题意: 给定n, m, k 以下n个整数 a[n] 以下m个整数 b[n] 用数字[0,k]构造一个n*m的矩阵 若有唯一解则输出这个矩阵.若有多解输出Not Unique,若无解输出Impossib ...

  7. HDU 4888 Redraw Beautiful Drawings

    网络流. $s$向每一个$r[i]$连边,容量为$r[i]$. 每一个$r[i]$向每一个$c[j]$连边,容量为$k$. 每一个$c[j]$向$t$连边容量为$c[j]$. 跑最大流,中间每一条边上 ...

  8. 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

    传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...

  9. Redraw Beautiful Drawings(hdu4888)网络流+最大流

    Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/O ...

随机推荐

  1. EF执行存储过程

    //执行strSql/procSql //返回受影响的行数 int i = dbsql.Database.ExecuteSqlCommand("exec getActionUrlId @na ...

  2. Javascript中typeof instanceof constructor的区别

    typeof typeof,是一个运算符,运算中需要一个操作数,运算的结果就是这个操作数的类型,运算的结果是一个字符串.他有一定的局限性,对于对象类型的值,只能得到一个object结果,却不能精确得到 ...

  3. Android手机分辨率基础知识(DPI,DIP计算)二

    dp = dip : device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不 ...

  4. 使用git命令提交远程github仓库的时候提示"rejected"(拒绝)解决办法

    今天使用在自己笔记本本地磁盘上使用Git命令行执行"git push"然后输入github的用户名和密码之后,报如下错误: ![rejected] master->maste ...

  5. python 图实现

    #coding:utf-8 __author__ = 'similarface' class Graph: def __init__(self,label,extra=None): #节点是类实例 s ...

  6. BOM头的来源

    类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM).它是一串隐藏的字符,用于让记事本等编辑器识别 ...

  7. RemoteWebDriver管理

    直接贴代码: @Parameters({"BrowserType","NodeIP","NodePort"}) public void be ...

  8. iOS 控制单个控制器旋转

    iOS 控制单个控制器旋转 控制单个ViewController 的旋转 //不旋转,保持竖屏 //iOS 5 - (BOOL) shouldAutorotateToInterfaceOrientat ...

  9. jq手风琴---点击时列表的左边距逐渐减小

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  10. js TAb

    有点乱,用到了自定义getByClass函数.sibling函数 <!DOCTYPE html> <html lang="en"> <head> ...