hdu 4888 Redraw Beautiful Drawings(最大流,判环)
pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888
加入一个源点与汇点,建图例如以下:
1. 源点 -> 每一行相应的点,流量限制为该行的和
2. 每一行相应的点 -> 每一列相应的点,流量限制为 K
3. 每一列相应的点 -> 汇点,流量限制为该列的和
求一遍最大流,若最大流与矩阵之和相等,说明有解,否则无解。推断唯一解,是推断残量网络中是否存在一个长度大于2的环。若存在说明有多解,否则有唯一解,解就是每条边行i->列j的流量。
#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
#define C 240
#define S 20
using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 810;
const int maxm = 160000+810; struct node
{
int u,v,w,next;
} edge[maxm << 1]; int cnt,head[maxn];
int n,m,k,s,t;
int nn[410],mm[410];
int maxflow;
int vis[maxn];
int dis[maxn]; void init()
{
cnt = 0;
memset(head,-1,sizeof(head));
} void add(int u, int v, int f)
{
edge[cnt] = (struct node){u,v,f,head[u]};
head[u] = cnt++; edge[cnt] = (struct node){v,u,0,head[v]};
head[v] = cnt++;
} bool bfs()
{
queue<int>que;
while(!que.empty()) que.pop();
memset(dis,-1,sizeof(dis));
dis[s] = 0;
que.push(s); while(!que.empty())
{
int u = que.front();
que.pop(); for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(dis[v] == -1 && edge[i].w)
{
dis[v] = dis[u]+1;
que.push(v);
}
}
}
if(dis[t] == -1)
return false;
return true;
} int dfs(int u, int delta)
{
if(u == t || delta == 0) return delta;
int dd;
int ret = 0;
for(int i = head[u]; i != -1 && delta; i = edge[i].next)
{
if(dis[edge[i].v] == dis[u]+1 && (dd = dfs(edge[i].v,min(delta,edge[i].w))))
{
edge[i].w -= dd;
edge[i^1].w += dd;
delta -= dd;
ret += dd;
if(delta == 0)
return ret;
}
}
dis[u] = -1;
return ret;
} int Dinic()
{
int ret = 0;
while(bfs())
{
ret += dfs(s,INF);
}
return ret;
} int dfs_1(int u,int fa)
{
for(int i=head[u]; i!=-1; i=edge[i].next)
{
if(i==(fa^1)) continue;
if(edge[i].w)
{
if(vis[edge[i].v]) return 1;
vis[edge[i].v]=1;
if(dfs_1(edge[i].v,i)) return 1;
vis[edge[i].v]=0;
}
}
return 0;
} void putmat()
{
int f[410][410];
printf("Unique\n");
for(int u = 1; u <= n; u++)
{
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(v > n && v <= n+m)
f[u][v-n] = k - edge[i].w;
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j < m; j++)
printf("%d ",f[i][j]);
printf("%d\n",f[i][m]);
}
} int main()
{
while(~scanf("%d %d %d",&n,&m,&k))
{
init();
s = 0;
t = n+m+1;
int sum1 = 0;
int sum2 = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d",&nn[i]);
add(s,i,nn[i]);
sum1 += nn[i];
for(int j = 1; j <= m; j++)
add(i,j+n,k);
} for(int i = 1; i <= m; i++)
{
scanf("%d",&mm[i]);
add(i+n,t,mm[i]);
sum2 += mm[i];
} if(sum1 != sum2)
{
printf("Impossible\n");
} else
{
maxflow = Dinic(); if(maxflow != sum1)
{
printf("Impossible\n");
}
else
{
int flag = 0;
memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i++)
{
if(dfs_1(i,-1))
{
flag = 1;
break;
}
}
if(flag == 1)
printf("Not Unique\n"); else
putmat();
}
}
}
return 0;
}
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 4888 Redraw Beautiful Drawings 最大流
好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...
- hdu 4888 Redraw Beautiful Drawings 网络流
题目链接 一个n*m的方格, 里面有<=k的数, 给出每一行所有数的和, 每一列所有数的和, 问你能否还原这个图, 如果能, 是否唯一, 如果唯一, 输出还原后的图. 首先对行列建边, 源点向行 ...
- HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...
- 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 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- HDU Redraw Beautiful Drawings 推断最大流是否唯一解
点击打开链接 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 ...
随机推荐
- oracle查询性能优化
原文http://www.cnblogs.com/cnjava/archive/2013/02/28/2937699.html 讲解的oracle数据库面对大数据如何优化查询.
- (转)淘淘商城系列——Redis持久化方案
http://blog.csdn.net/yerenyuan_pku/article/details/72858975 Redis中设置key的过期时间 Redis中的expire命令用于设置key的 ...
- 安卓app测试之内存监控
一.通过Dumpsys 来取值 1.adb shell dumpsys meminfo 获取的所有进程的内存信息,以及总内存,剩余内存,使用的内存等信息. 2.想获得某一进程内存的详细信息,在后面加上 ...
- 扩增子分析解读4去嵌合体 非细菌序列 生成代表性序列和OTU表
本节课程,需要先完成 扩增子分析解读1质控 实验设计 双端序列合并 2提取barcode 质控及样品拆分 切除扩增引物 3格式转换 去冗余 聚类 先看一下扩增子分析的整体流程,从下向上逐层分析 分 ...
- replace、replaceAll、replaceFirst
replace.replaceAll.replaceFirst这三个函数会java的同学估计都用过,笔者已经用了2年多,可是,我们真的懂他们吗? 概述一下他们三个的用法: · replace(Char ...
- 51nod 1050 循环数组最大子段和【动态规划】
N个整数组成的循环序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的连续的子段和的最大值(循环序列是指n个数围成一个圈,因此需要考虑a[n-1],a[n] ...
- DTD 文件的引入
MyBatis 有两种配置文件:核心配置文件(mybatis- config.xml)和 SQL 映射文件(mapper.xml).这两种配置文件都需要手动引入各自的 DTD 文件(mybatis-3 ...
- NumPy 学习笔记(四)
NumPy 算术函数: 1.numpy.reciprocal(arr) 返回参数逐个元素的倒数 2.numpy.power(one, two) 将第一个输入数组中的元素作为底数,计算它与第二个输入数组 ...
- SVM简单上手示例
转载自 百度知道 id:风_南(https://zhidao.baidu.com/usercenter?uid=e9904069236f25705e799313) 转载只为方便学习复习,侵删. 在用s ...
- L2-006. 树的遍历(不建树)
L2-006. 树的遍历 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(<=30),是二叉树中结点 ...