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

我们建一个二部图。左边是行,右边是列,建个源点与行建边,容量是该行的和。列与新建的汇点建边。容量是该列的和,最后每行与每列建边,容量为题意中的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. Android开机logo修改方法 【转】

    本文转载自:http://blog.csdn.net/qq258711519/article/details/7766303 一体机平台开机logo修改方法 1:修改Kernel中的Logo: 若是要 ...

  2. hdoj--1598--find the most comfortable road

    find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  3. solaris&nbsp;10&nbsp;关闭ftp、telnet

    安装solaris10,启动后发现找不到ftp.telnet的关闭方法, 管理命令 svcadm(服务状态管理,启动.停止等) # svcs 查看当前所有的服务状态,可以使用|管道符重定向作更个性化的 ...

  4. BZOJ 1537 cdq分治

    思路: 我只是想写一下cdq-- 二维偏序 一维排序 一维cdq分治 (我忘了归并排序怎么写了,,,) 写了个sort- 复杂度是O(nlog^2n) //By SiriusRen #include ...

  5. unity3d 鼠标事件

    using UnityEngine; using System.Collections; public class mouse : MonoBehaviour { //private Vector3 ...

  6. PhotoZoom Classic 7怎么样?对电脑和系统要求高不高?

    PhotoZoom Classic 7怎么样?对电脑和系统要求高不高? 相较于更专业PhotoZoom Pro,标准版本的PhotoZoom Classic 7更适用于日常工作中的图片放大处理,例如在 ...

  7. 修改XtraMessageBox的内容字体大小

    修改XtraMessageBox的内容字体大小 public static DialogResult Show(UserLookAndFeel lookAndFeel, IWin32Window ow ...

  8. 【转】【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    原文地址:http://www.cnblogs.com/baiboy/p/orc3.html 阅读目录 目录 RAC 工作原理和相关组件 ClusterWare 架构 RAC 软件结构 集群注册(OC ...

  9. BZOJ 4827: [Hnoi2017]礼物 FFT_多项式_卷积

    题解稍后在笔记本中更新 Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r&q ...

  10. ES2015 模板字符串 ``

    js中类似`${xx,yy}`的语句是什么意思? `string` 是模板字符串,ES2015新增的符号. var x = 'a', y = 'b'; var z = `${x,y}`; //'b' ...