题目

Source

http://acm.hdu.edu.cn/showproblem.php?pid=4888

Description

Alice and Bob are playing together. Alice is crazy about art and she has visited many museums around the world. She has a good memory and she can remember all drawings she has seen.

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.

Input

The input contains mutiple testcases.

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.

Output

For each testcase, if there is no solution for Bob, output "Impossible" in one line(without the quotation mark); if there is only one solution for Bob, output "Unique" in one line(without the quotation mark) and output an N * M matrix in the following N lines representing Bob's unique solution; if there are many ways for Bob to redraw the drawing, output "Not Unique" in one line(without the quotation mark).

Sample Input

2 2 4
4 2
4 2
4 2 2
2 2 5 0
5 4
1 4 3
9
1 2 3 3

Sample Output

Not Unique
Impossible
Unique
1 2 3 3

分析

题目大概说有一个矩阵,已知各个单元的值在0到k之间以及各行各列的和,要求还原该矩阵,如果唯一的话就输出解。

经典的构图了吧,POJ2396

  • 把行、列看成点,各单元看成边

而问题关键在于判定最大流唯一性。

这个结论是,残量网络不存在环是最大流唯一的充要条件。找到环绕着一圈调整一下环上边的流量,比如流量-1(同时对应的反向边或者正向边流量+1),这样又会是一个满足平衡条件的最大流。

在残量网络中找环,不能用拓扑排序。因为正向边和反向边应该要看成一体,即如果统计了正向边贡献的出入度,那么反向边的出入度就不需要统计了,反之亦然,而我们没法确定各边是选正向还是反向。

那么环就用搜索找了:

bool dfs(int u,int fa){
vis[u]=1;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(v==fa || edge[i].cap==edge[i].flow) continue;
if(vis[v]) return 1;
if(dfs(v,u)) return 1;
}
vis[u]=0;
return 0;
}

不过这个怎么看都是指数级时间复杂度。

我在这个博客看到了删边的做法。确实,回溯后说明往当前这条边走是找不到环的,以后不必要再往这条边走,这样每条边最多都只走一次就保证了时间复杂度为多项式级别的了。

不过我看不懂那个博客的删边方式,我就比较low地标记删除的边,遇到被标记的就跳过。。不过这么做HDU4975是TLE的;于是我就自己想了想怎么真正地删边,然后实现了下,还是TLE,这不是线性时间复杂度了吗?。。好吧那题我选择放弃。

另外还有一个可以优化的是枚举环的起点只要枚举容量网络中行对应的点,我大概想了下是因为这题建图方式构成了二分图,那样从列对应的点出发找到环一定是会经过行对应的点的,于是从行对应的点出发也能形成这个环。

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 888
#define MAXM 444*888 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-1,sizeof(level));
memset(gap,0,sizeof(gap));
level[vt]=0;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
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(level[v]!=-1) continue;
level[v]=level[u]+1;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-1,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=0,aug=INF;
gap[0]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^1].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==0) break;
level[u]=minlevel+1;
gap[level[u]]++;
u=pre[u];
}
return flow;
} bool vis[MAXN]; bool dfs(int u,int fa){
vis[u]=1;
for(int i=head[u],pre=i; i!=-1; ){
int v=edge[i].v;
if(v==fa || edge[i].cap==edge[i].flow){
pre=i;
i=edge[i].next;
continue;
}
if(vis[v]) return 1;
if(dfs(v,u)) return 1;
if(i==head[u]){
i=edge[i].next;
head[u]=i;
}else{
i=edge[i].next;
edge[pre].next=i;
}
}
vis[u]=0;
return 0;
} int ans[444][444]; int main(){
int n,m,k,a;
while(~scanf("%d%d%d",&n,&m,&k)){
vs=0; vt=n+m+1; NV=vt+1; NE=0;
memset(head,-1,sizeof(head));
int row=0,col=0;
for(int i=1; i<=n; ++i){
scanf("%d",&a);
addEdge(vs,i,a);
row+=a;
}
for(int i=1; i<=m; ++i){
scanf("%d",&a);
addEdge(i+n,vt,a);
col+=a;
}
if(row!=col){
puts("Impossible");
continue;
}
for(int i=1; i<=n; ++i){
for(int j=1; j<=m; ++j){
addEdge(i,j+n,k);
}
}
if(ISAP()!=row){
puts("Impossible");
continue;
}
for(int u=1; u<=n; ++u){
for(int i=head[u]; i!=-1; i=edge[i].next){
if(i&1) continue;
int v=edge[i].v-n;
ans[u][v]=edge[i].flow;
}
}
bool flag=1;
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; ++i){
if(dfs(i,i)){
flag=0;
break;
}
}
if(!flag){
puts("Not Unique");
continue;
}
puts("Unique");
for(int i=1; i<=n; ++i){
for(int j=1; j<=m; ++j){
if(j!=1) putchar(' ');
printf("%d",ans[i][j]);
}
putchar('\n');
}
}
return 0;
}

HDU4888 Redraw Beautiful Drawings(最大流唯一性判定:残量网络删边判环)的更多相关文章

  1. hdu4888 Redraw Beautiful Drawings 最大流+判环

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

  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. hdu4888 Redraw Beautiful Drawings(最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4888 题意:给一个矩阵没行的和和每列的和,问能否还原矩阵,如果可以还原解是否唯一,若唯一输出该矩阵. ...

  5. hdu 4888 Redraw Beautiful Drawings 最大流

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

  6. hdu4888 Redraw Beautiful Drawings

    14更多学校的第二个问题 网络流量   分别以行,列作为结点建图 i行表示的结点到j列表示的结点的流量便是(i, j)的值 跑遍最大流   若满流了便是有解   推断是否unique  就是在残余网络 ...

  7. 最小割最大流定理&残量网络的性质

    最小割最大流定理的内容: 对于一个网络流图 $G=(V,E)$,其中有源点和汇点,那么下面三个条件是等价的: 流$f$是图$G$的最大流 残量网络$G_f$不存在增广路 对于$G$的某一个割$(S,T ...

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

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

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

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

随机推荐

  1. 常用iOS的第三方框架

    图像:1.图片浏览控件MWPhotoBrowser       实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网络下载图片并进行缓存.可对图片进行缩放等 ...

  2. DB2 create partitioned table

    在Z上和开放平台上的创建方法还不太一样,两套人马开发出来的就是牛! 蛋疼…… 贴不同类型的几个例子感受一下,Z上的ASC,DESC不见了: CREATE TABLE foo(a INT) PARTIT ...

  3. DB2 Z/os Load utility 使用

    Use the LOAD online utility to load one or more tables of a table space. The LOAD utility loads reco ...

  4. 三、jQuery--Ajax基础--Ajax全接触--JSON

    JSON基本概念 JSON:JavaScript对象表示法(JavaScript Object Notation) JSON是存储和交换文本信息的语法,类似XML.它采用键值对的方式来组织,易于人们阅 ...

  5. SQL学习笔记----更改SQL默认的端口号

    1.SQLServer配置管理器----SQLServer网络配置----MSSQLSERVER的协议---TCP/IP(已启用)---IP地址 清空素有的IP,在IPALL下更改默认的端口: 2. ...

  6. ASP.NET MVC中的Razor语法

    1.Razor的基本语法 @* 多行代码时需要包含在大括号内{}和每句代码后都需要加分号; *@ @{ ViewBag.Title = "Index"; ViewBag.Name ...

  7. C# 读取CSV文件

    CSV文件是用逗号作为分隔符的,所以如果是简单的CSV文件,用split(',')就可以了. 但是Excel 编辑CSV文件,且内容中有逗号,得到的csv文件如下:"aaa,aaa" ...

  8. 【转载】 Pyqt QStackedWidget堆栈窗体

    转载地址: http://blog.csdn.net/a649518776/article/details/6636578 下面用代码实现上面窗口的设计 # -*- coding: utf-8 -*- ...

  9. GoLang搞一个基本的HTTP服务

    慢慢和python的对应一下看看. package main import ( "fmt" "net/http" "strings" &qu ...

  10. 蓝桥杯 算法训练 Torry的困惑(基本型)(水题,筛法求素数)

    算法训练 Torry的困惑(基本型) 时间限制:1.0s   内存限制:512.0MB      问题描述 Torry从小喜爱数学.一天,老师告诉他,像2.3.5.7……这样的数叫做质数.Torry突 ...