思路:一開始以为是高斯消元什么的。想让队友搞,结果队友说不好搞,可能是网络流。我恍然,思路立刻就有了。

我们建一个二部图。左边是行,右边是列,建个源点与行建边,容量是该行的和。列与新建的汇点建边。容量是该列的和,最后每行与每列建边,容量为题意中的k。建边如图:







跑一遍最大流,假设最大流等于行的和且等于列的和,那么就是有解的,否则无解。这样我们得到了一组解,行i到列j的流量即为i行j列的大小。之后便是推断是否有多种情况了。

基本思路是这种,我们看下图:





有多解的情况一定能够找到这种4个位置:AB同行。CD同行。AC同列。BD同列。而且他们符合一下两种情况的当中一种:

1、AD未达到k(可变大)。BC不是0(可减小)

2、AD不是0(可减小)。BC未达到k(可变大)

只是枚举的话复杂度太高了。这里须要优化下。我建了一个二维数组cc[i][j],代表之前行是否有第i个可变大,第j个可减小的情况。这里枚举每一行,每一行再枚举两个位置i和j,假设当前行有i和j使得第i能够减小、第j个能够变大而且cc[i][j]为1,那么一定有多解。这里假设cc[i][j]为0。那么继续。同一时候cc[j][i]赋为1。这种话就避免了最坏O(400^4)的复杂度。而变成了最多O(400^3)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<cmath>
#define maxn 1<<29
using namespace std;
struct edge
{
int from,to,cap,flow;
};
vector<int>g[888];
vector<edge>edges;
int m,n,ma;
bool vis[888];
int d[888];
int cur[888];
int fl[444][444];
bool cc[444][444];
void init()
{
edges.clear();
int mm=m+n+1;
for(int i=0;i<=mm;i++)g[i].clear();
}
void add(int u,int v,int c)
{
edges.push_back((edge){u,v,c,0});
g[u].push_back(edges.size()-1);
edges.push_back((edge){v,u,0,0});
g[v].push_back(edges.size()-1);
}
bool bfs(int s,int t)
{
memset(vis,0,sizeof(vis));
queue<int>q;
q.push(s);
d[s]=0;
vis[s]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
int size=g[u].size();
for(int i=0;i<size;i++)
{
edge &e=edges[g[u][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
vis[e.to]=1;
d[e.to]=d[u]+1;
q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int u,int t,int mi)
{
if(u==t||mi==0)return mi;
int flow=0,f;
int size=g[u].size();
for(int &i=cur[u];i<size;i++)
{
edge &e=edges[g[u][i]];
if(d[u]+1==d[e.to]&&(f=dfs(e.to,t,min(mi,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[g[u][i]^1].flow-=f;
flow+=f;
mi-=f;
if(mi==0)break;
}
}
return flow;
}
int dinic(int s,int t)
{
int flow=0;
while(bfs(s,t))
{
memset(cur,0,sizeof(cur));
flow+=dfs(s,t,maxn);
}
return flow;
}
bool go()
{
for(int i=1;i<=n;i++)
{
int size=g[i].size();
for(int j=0;j<size;j++)
{
edge &e=edges[g[i][j]];
if(e.to>n&&e.to<=m+n)
{
//cout<<e.from<<" "<<e.to<<" "<<e.flow<<endl;
fl[i][e.to-n]=e.flow;
}
}
}
memset(cc,0,sizeof(cc));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=j+1;k<=m;k++)
{
bool v1=0,v2=0;
if(fl[i][j]!=ma&&fl[i][k]!=0)
{
if(cc[k][j])return true;
v1=1;
}
if(fl[i][j]!=0&&fl[i][k]!=ma)
{
if(cc[j][k])return true;
v2=1;
}
if(v1)cc[j][k]=1;
if(v2)cc[k][j]=1;
}
}
}
return false;
}
int main()
{
int u,v,c;
int s1,s2;
while(scanf("%d%d%d",&n,&m,&ma)!=EOF)
{
init();
s1=s2=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&c);
add(0,i,c);
s1+=c;
for(int j=1;j<=m;j++)
{
add(i,n+j,ma);
}
}
for(int i=1;i<=m;i++)
{
scanf("%d",&c);
add(n+i,m+n+1,c);
s2+=c;
}
int ans=dinic(0,m+n+1);
if(ans!=s1||ans!=s2)printf("Impossible\n");
else if(go())printf("Not Unique\n");
else
{
printf("Unique\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%d",fl[i][j]);
if(j==m)printf("\n");
else printf(" ");
}
}
}
}
return 0;
}

hdu 4888 2014多校第三场1002 Redraw Beautiful Drawings 网络流的更多相关文章

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

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

  2. 2014多校第三场1005 || HDU 4891 The Great Pan(模拟)

    题目链接 题意 : 给你n行字符串,问你有多少种理解方式.有两大类的理解 (1){A|B|C|D|...}代表着理解方式可以是A,可以是B或C或者D. (2)$blah blah$,在$$这两个符号中 ...

  3. hdu-4893-Wow! Such Sequence!-线段树【2014多校第三场-J】

    题意:一个初始为0的数组,支持三种操作:1.向第k个数添加d,(|d| < 2^31);2.把[l, r]区间内的数字都换成与它最相近的Fibonacci数;3.询问[l, r]区间的和. 思路 ...

  4. 2014多校第十场1002 || HDU 4972 A simple dynamic programming problem

    题目链接 题意 : 每次无论哪个队投进一个篮球,就记下现在两队比分的差值,问你最后的结果有多少种情况. 思路 : 该题实在是不好理解,最后的结果有多少种情况就是说不管中间过程怎么来的,只要最后结果不一 ...

  5. HDU 4622 多校第三场1002 后缀自动机

    比赛的时候我是用后缀数组的,但是T了. 赛后看了解题报告说,后缀数组貌似是卡你常数的时间,我算了下复杂度O(T * Q * n).这是10 ^ 8,但是考虑到每次询问的时候都要重新构造字符,所以那个n ...

  6. hdu 4888 Redraw Beautiful Drawings 网络流

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

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

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

  8. 2018 HDU多校第三场赛后补题

    2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...

  9. hdu 5288||2015多校联合第一场1001题

    pid=5288">http://acm.hdu.edu.cn/showproblem.php?pid=5288 Problem Description OO has got a ar ...

随机推荐

  1. xml配置文件中的转义字符

    https://stackoverflow.com/questions/14607920/the-character-breaks-passwords-that-are-stored-in-the-w ...

  2. dns tunnel 使用 nishang 下载TXT里的cmd(TXT里)实现CC command+ ceye实现数据外发

    摘自:https://hk.saowen.com/a/a06909f1c57cb8452db969b3deede4151de42a7d69f4bb52c5bf027033fb91bd Powershe ...

  3. nginx 限制ip/限制访问路径

    一.多站点统一限IP vim nginx.conf allow 127.0.0.1; deny all; # 以上代码解释: # deny all; 限制所有的ip # allow ip; 除了 这个 ...

  4. POJ 2513 trie树+并查集判断无向图的欧拉路

    生无可恋 查RE查了一个多小时.. 原因是我N define的是250500 应该是500500!!!!!!!!! 身败名裂,已无颜面对众人.. 吐槽完了 我们来说思路... 思路: 判有向图能否形成 ...

  5. .net几种文件下载的方法

    .Net文件下载方式.... 之前在写上传文件.下载文件的时候,发现Response对象里面有好几种下载文件的方式,之后自己亲自实践了这几种方法,记录下以便以后复习... WriteFile文件下载 ...

  6. vue-router 原理解析

    “更新视图但不重新请求页面”是前端路由原理的核心之一,

  7. android黑科技系列——破解游戏之修改金币数

    我们在玩游戏的时候总是会遇到一些东东需要进行购买的,但是我们可能又舍不得花钱,那么我们该怎么办呢?那就是用游戏外挂吧!我们这里说的是Android中的游戏,在网上搜索一下移动端游戏外挂,可能会找到一款 ...

  8. 2019苏州凯美瑞德Java开发面试

    第四家Kmerit,苏州园区,出门晚了差点迟到,一点五十五到达,先花了一小时笔试,后来两个人技术面试,四点二十出了大楼. 一.笔试 1.单选,知识点很散,涉及数据结构链表,数组,树,堆,数据库,网络, ...

  9. R 连接DB2数据库,并制作词图

    #写在前面的话:此教程主要是用R连接了DB2数据库,并进行文本分析,制作了词图 #教程为markdown编写 ---title: "网站留言分析"output: html_docu ...

  10. DBGridEh checkbox的一个问题

    function TCustomDBGridEh.CheckBeginRowMoving(MouseX, MouseY: Integer; CheckInOnly: Boolean): Boolean ...