HDU Redraw Beautiful Drawings 推断最大流是否唯一解
Redraw Beautiful Drawings
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1660 Accepted Submission(s): 357
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.
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.
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).
2 2 4
4 2
4 2
4 2 2
2 2 5 0
5 4
1 4 3
9
1 2 3 3
Not Unique
Impossible
Unique
1 2 3 3
给你一个n*m的矩阵,然后个格子里面有一个小于k的数,而且告诉你每行和每列的和,让你求是否存在解,并推断是否唯一。
//515MS 7304K
#include<stdio.h>
#include<string.h>
#define M 1007
int s,t,n,m,k,sum1,sum2;
int row[M],col[M],vis[M],g[M][M];
const int MAXN=20010;//点数的最大值
const int MAXM=880010;//边数的最大值
const int INF=0x3f3f3f3f;
struct Node
{
int from,to,next;
int cap;
}edge[MAXM];
int tol;
int head[MAXN];
int dis[MAXN];
int gap[MAXN];//gap[x]=y :说明残留网络中dis[i]==x的个数为y
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
edge[tol].from=u;
edge[tol].to=v;
edge[tol].cap=w;
edge[tol].next=head[u];
head[u]=tol++;
edge[tol].from=v;
edge[tol].to=u;
edge[tol].cap=0;
edge[tol].next=head[v];
head[v]=tol++;
}
void BFS(int start,int end)
{
memset(dis,-1,sizeof(dis));
memset(gap,0,sizeof(gap));
gap[0]=1;
int que[MAXN];
int front,rear;
front=rear=0;
dis[end]=0;
que[rear++]=end;
while(front!=rear)
{
int u=que[front++];
if(front==MAXN)front=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]!=-1)continue;
que[rear++]=v;
if(rear==MAXN)rear=0;
dis[v]=dis[u]+1;
++gap[dis[v]];
}
}
}
int SAP(int start,int end)
{
int res=0,nn=end+1;
BFS(start,end);
int cur[MAXN];
int S[MAXN];
int top=0;
memcpy(cur,head,sizeof(head));
int u=start;
int i;
while(dis[start]<nn)
{
if(u==end)
{
int temp=INF;
int inser;
for(i=0;i<top;i++)
if(temp>edge[S[i]].cap)
{
temp=edge[S[i]].cap;
inser=i;
}
for(i=0;i<top;i++)
{
edge[S[i]].cap-=temp;
edge[S[i]^1].cap+=temp;
}
res+=temp;
top=inser;
u=edge[S[top]].from;
}
if(u!=end&&gap[dis[u]-1]==0)//出现断层,无增广路
break;
for(i=cur[u];i!=-1;i=edge[i].next)
if(edge[i].cap!=0&&dis[u]==dis[edge[i].to]+1)
break;
if(i!=-1)
{
cur[u]=i;
S[top++]=i;
u=edge[i].to;
}
else
{
int min=nn;
for(i=head[u];i!=-1;i=edge[i].next)
{
if(edge[i].cap==0)continue;
if(min>dis[edge[i].to])
{
min=dis[edge[i].to];
cur[u]=i;
}
}
--gap[dis[u]];
dis[u]=min+1;
++gap[dis[u]];
if(u!=start)u=edge[S[--top]].from;
}
}
return res;
} void build()
{
sum1=0,sum2=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&row[i]);
sum1+=row[i];
addedge(s,i,row[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d",&col[i]);
sum2+=col[i];
addedge(n+i,t,col[i]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
addedge(i,n+j,k);
} bool iscycle(int u,int fa)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
if(i==(fa^1))continue;
if(edge[i].cap)
{
if(vis[edge[i].to])return true;
vis[edge[i].to]=true;
if(iscycle(edge[i].to,i))return true;
vis[edge[i].to]=false;
}
}
return false;
}
void solve()
{
if(sum1!=sum2){printf("Impossible\n");return;}
int anss=SAP(s,t);
//printf("anss=%d\n",anss);
if(anss!=sum1){printf("Impossible\n");return;}
memset(vis,false,sizeof(vis));
int flag=0;
for(int i=1;i<=n;i++)//推断残留网络是否存在环
if(iscycle(i,-1))
{flag=1;break;}
if(flag)printf("Not Unique\n");
else
{
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].to;
if(v>n&&v<=n+m)
g[u][v-n]=k-edge[i].cap;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++)
printf("%d ",g[i][j]);
printf("%d\n",g[i][m]);
}
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
s=0,t=n+m+1;
init();
build();
solve();
}
}
HDU Redraw Beautiful Drawings 推断最大流是否唯一解的更多相关文章
- 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(最大流唯一性判定:残量网络删边判环)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4888 Description Alice and Bob are playing toget ...
- hdu4888 Redraw Beautiful Drawings(最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4888 题意:给一个矩阵没行的和和每列的和,问能否还原矩阵,如果可以还原解是否唯一,若唯一输出该矩阵. ...
- 【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 ...
- 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. 源点 -> 每一行相应 ...
- hdu 4888 Redraw Beautiful Drawings 最大流
好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...
随机推荐
- 最艰难的采访IT公司ThoughtWorks代码挑战——FizzBuzzWhizz游戏
最近的互联网招聘平台拉勾网在五月推出了"最艰难的采访IT公司"码挑战活动,评选出了5个最难面试的IT公司,即:ThoughtWorks.Google.Unisys.Rackspac ...
- NUnit3 Test Adapter vs2015
NUnit的安装 前言:NUnit是什么? NUnit 是一个单元测试框架,专门针对于.NET来写的.NUnit是xUnit家族种的第4个主打产品,完全由C#语言来编写,并且编写时充分利用了许多.NE ...
- asp.net web api KnownTypeAttribute
项目里用到了继承,在序列化的时候遇到了问题. 源代码 public class Segment { public SegmentType Type { get; set; } public strin ...
- C、C++用指针引用的差异
1:并引述之间的区别在概念的指针 参考是可变的别名.例如 int m; int &n=m; 引用作为一个别名.它在逻辑上不是独立的.它的存在具有依附性.所以引用必须在一開始就被初始化.并且其引 ...
- bash no such file or directory in ubuntu 1404
我在我的今天macbook pro retina 里面安装的虚拟机ubuntu 1404. 当我试图执行cadence ncverilog时间.ubuntu终端错误"bash no such ...
- C#
抽象类其中创建一个静态方法
</pre><pre name="code" class="csharp"><span style="font-size ...
- MapXtreme DJ最短路径算法 全路径搜索算法
包括最短路径,全路径搜索算法演示程序请在http://pan.baidu.com/s/1jG9gKMM#dir/path=%2F%E4%BA%A7%E5%93%81%2FDemos 找 ShortWa ...
- backup mysql for xtrabackup with xbstream and lz4
极品暂时mysql加入一个实例,采用xtrabackup最简单的速度. 在现有数据节点上: /home/work/app/xtrabackup-2.2.3/innobackupex --ibbacku ...
- hadoop2.0的datanode数据存储文件夹策略的多个副本
在hadoop2.0在,datanode数据存储盘选择策略有两种方式复制: 首先是要遵循hadoop1.0磁盘文件夹投票,实现类:RoundRobinVolumeChoosingPolicy.java ...
- height/innerHeight/outerHeight
<script> $(document).ready(function(){ alert("height:"+$("#div").height()) ...