HDU4888 Redraw Beautiful Drawings(最大流唯一性判定:残量网络删边判环)
题目
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(最大流唯一性判定:残量网络删边判环)的更多相关文章
- hdu4888 Redraw Beautiful Drawings 最大流+判环
hdu4888 Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/6553 ...
- 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. 源点 -> 每一行相应 ...
- hdu4888 Redraw Beautiful Drawings(最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4888 题意:给一个矩阵没行的和和每列的和,问能否还原矩阵,如果可以还原解是否唯一,若唯一输出该矩阵. ...
- hdu 4888 Redraw Beautiful Drawings 最大流
好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...
- hdu4888 Redraw Beautiful Drawings
14更多学校的第二个问题 网络流量 分别以行,列作为结点建图 i行表示的结点到j列表示的结点的流量便是(i, j)的值 跑遍最大流 若满流了便是有解 推断是否unique 就是在残余网络 ...
- 最小割最大流定理&残量网络的性质
最小割最大流定理的内容: 对于一个网络流图 $G=(V,E)$,其中有源点和汇点,那么下面三个条件是等价的: 流$f$是图$G$的最大流 残量网络$G_f$不存在增广路 对于$G$的某一个割$(S,T ...
- Redraw Beautiful Drawings(hdu4888)网络流+最大流
Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/O ...
- HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...
随机推荐
- Tmux的安装、使用与配置
tmux 安装.使用.配置 因上线需求,故需要使用tumx,方便上线 tmux功能 提供了强大的.易于使用的命令行界面 可横向.纵向分割窗口 窗格可以自由移动和调整大小,或者直接利用四个预设布局之一 ...
- September 8th 2016 Week 37th Thursday
The secret of high-impact business is early preparation. 高效商务,赢在未雨绸缪. Early and best preparation is ...
- 搞笑世界杯(codevs 1060)
题目描述 Description 随着世界杯小组赛的结束,法国,阿根廷等世界强队都纷纷被淘汰,让人心痛不已. 于是有 人组织了一场搞笑世界杯,将这些被淘汰的强队重新组织起来和世界杯一同比赛.你和你的朋 ...
- Mac平台下Opencv开发环境搭建
OpenCV(Open Source Computer Vision Library),是一个开源的跨平台的计算机视觉库,它实现了图像处理和计算机视觉领域的很多通用算法,可以在多种计算机平台上运行,支 ...
- UVA 111 History Grading
读题读了好久,其实就是在输入数据时要对数据的位置进行相应的改变 #include<iostream> #include<cstring> #include<cstdio& ...
- java07课堂作业
一.动手动脑:多层的异常捕获-1 阅读以下代码(CatchWho.java),写出程序运行结果: public class CatchWho { public static void main(Str ...
- js 倒计时点击和当前时间
<input id="btn" type="submit" value="确定" disabled="disabled&qu ...
- DBCC常用命令小汇
DBCC是SQL Server提供的一组控制台命令,功能很强大,掌握一些必要的语句,对操作数据库有不少帮助,所以决定整理一下,发现已有不少类似的整理,减少了不少工作,归类如下: 一.DBCC 帮助类命 ...
- Babelfish(二分查找,字符串的处理略有难度,用sscanf输入)
Babelfish Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 28581 Accepted: 12326 题目链接: ...
- Vmware 中安装Unix
准备 1. ubuntu 14.10 下载地址: 官网下载链接 http://www.ubuntu.com/download/desktop 官方版本库 http://releases.ubuntu. ...