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

添加一个源点与汇点,建图如下:

1. 源点 -> 每一行对应的点,流量限制为该行的和

2. 每一行对应的点 -> 每一列对应的点,流量限制为 K

3. 每一列对应的点 -> 汇点,流量限制为该列的和

求一遍最大流,若最大流与矩阵之和相等,说明有解,否则无解。判断唯一解,是判断残量网络中是否存在一个长度大于2的环,若存在说明有多解,否则有唯一解,解就是每条边行i->列j的流量。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cstdlib>
using namespace std; const int maxn=500,maxm=maxn*maxn;
int next[maxm*2],num[maxm*2],r[maxm*2],a[maxn*2],row_sum[maxn],col_sum[maxn],n,m,K,tt,T,d[maxn*2],st[maxn*2],cod[maxn][maxn];
int h[maxn*2],vh[maxn*2];
bool don[maxm*2],in[maxn*2]; void insert(int x,int y,int rr)
{
next[++tt]=a[x];num[tt]=y;r[tt]=rr;a[x]=tt;
next[++tt]=a[y];num[tt]=x;r[tt]=0;a[y]=tt;
} void construct()
{
tt=1;T=n+m+1;
for (int i=0;i<=T;i++) a[i]=0;
for (int i=1;i<=n;i++) insert(0,i,row_sum[i]);
for (int i=1;i<=m;i++) insert(i+n,T,col_sum[i]);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
insert(i,j+n,K);
cod[i][j]=tt;
}
}
} int dfs(int x,int y)
{
if (x==T) return y;
int sig=st[x],minh=T+1;
do
{
if (r[st[x]])
{
if (h[num[st[x]]]+1==h[x])
{
int k=dfs(num[st[x]],min(y,r[st[x]]));
if (k)
{
r[st[x]]-=k;
r[st[x]^1]+=k;
return k;
}
}
minh=min(minh,h[num[st[x]]]+1);
if (h[0]>T) return 0;
}
st[x]=next[st[x]];
if (st[x]==0) st[x]=a[x];
}while (sig!=st[x]);
if (vh[h[x]]--==0) h[0]=T+1;
vh[h[x]=minh]++;
return 0;
} int max_flow()
{
for (int i=0;i<=T;i++) h[i]=vh[i]=0;
for (int i=0;i<=T;i++) st[i]=a[i];
vh[0]=T+1;
int ret=0;
while (h[0]<=T) ret+=dfs(0,K+1);
return ret;
} /*bool find_circle()
{
deque <int> q;
for (int i=0;i<=T;i++) d[i]=0;
for (int i=0;i<=T;i++)
{
for (int p=a[i];p;p=next[p])
{
if (r[p]) d[i]++;
}
if (d[i]==0) q.push_back(i);
}
int cnt=T+1;
while (!q.empty())
{
int x=q.front();
cnt--;
q.pop_front();
for (int p=a[x];p;p=next[p])
{
if (r[p^1])
{
d[num[p]]--;
if (d[num[p]]==0) q.push_back(num[p]);
}
}
}
return cnt;
}*/ bool visit(int x,int ed)
{
if (don[ed])
return in[x];
don[ed]=true;
in[x]=true;
for (int p=a[x];p;p=next[p])
{
if (r[p] && (ed^p)!=1)
if (visit(num[p],p)) return true;
}
in[x]=false;
return false;
} bool find_circle()
{
for (int i=0;i<=T;i++) in[i]=false;
for (int i=1;i<=tt;i++) don[i]=false;
int col=0;
for (int i=2;i<=tt;i++)
{
if (r[i] && !don[i])
{
in[num[i^1]]=true;
if (visit(num[i],i)) return true;
in[num[i^1]]=false;
}
}
return false;
} void print_scheme()
{
printf("Unique\n");
for (int i=1;i<=n;i++)
{
printf("%d",r[cod[i][1]]);
for (int j=2;j<=m;j++) printf(" %d",r[cod[i][j]]);
printf("\n");
}
} int main()
{
while (scanf("%d%d%d",&n,&m,&K)!=EOF)
{
int tmp=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&row_sum[i]);
tmp+=row_sum[i];
}
int sum=tmp;
for (int i=1;i<=m;i++)
{
scanf("%d",&col_sum[i]);
tmp-=col_sum[i];
}
if (tmp)
{
printf("Impossible\n");
continue;
}
construct();
if (max_flow()<sum)
{
printf("Impossible\n");
continue;
}
if (find_circle())
{
printf("Not Unique\n");
}else print_scheme();
} return 0;
}

hdu 4888 最大流慢板的更多相关文章

  1. hdu 4888 最大流给出行列和求矩阵

    第一步,考虑如何求是否有解.使用网络流求解,每一行和每一列分别对应一个点,加上源点和汇点一共有N+M+2个点.有三类边: 1. 源点 -> 每一行对应的点,流量限制为该行的和 2. 每一行对应的 ...

  2. 2014联合三所学校 (HDU 4888 HDU 4891 HDU 4893)

    HDU 4891 The Great Pan 注册标题  他怎么说,你怎么样  需要注意的是乘法时,它会爆炸int 代码: #include<iostream> #include<c ...

  3. HDU 1532 最大流入门

    1.HDU 1532 最大流入门,n个n条边,求第1点到第m点的最大流.只用EK做了一下. #include<bits/stdc++.h> using namespace std; #pr ...

  4. hdu 4888 Redraw Beautiful Drawings(最大流,判环)

    pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888 加入一个源点与汇点,建图例如以下: 1. 源点 -> 每一行相应 ...

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

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

  6. hdu 4888 Redraw Beautiful Drawings 最大流

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

  7. hdu 4289 最大流拆点

    大致题意:     给出一个又n个点,m条边组成的无向图.给出两个点s,t.对于图中的每个点,去掉这个点都需要一定的花费.求至少多少花费才能使得s和t之间不连通. 大致思路:     最基础的拆点最大 ...

  8. Going Home HDU - 1533 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 给一个网格图,每两个点之间的匹配花费为其曼哈顿距离,问给每个的"$m$"匹配到一个&q ...

  9. hdu 4975 最大流快版

    http://acm.hdu.edu.cn/showproblem.php?pid=4975 给出每行每列的和,问是否存在这样的表格:每个小格放的数字只能是0--9. 直接用第八场最大流模板. #in ...

随机推荐

  1. scala -- 传名参数

    object Test{ def main(args: Array[String]): Unit = { def test(code : => Unit){// 传名参数 不计算函数值,而是把函 ...

  2. one by one 项目 part 5

    问题汇总 一.Can't connect to MySQL server on 'localhost' (10061)翻译:不能连接到 localhost 上的mysql分析:这说明“localhos ...

  3. WEB性能测试工具

    做Web开发,难免要对自己开发的页面进行性能检测,自己写工具检测,工作量太大.网上有几款比较成熟的检测工具,以下就介绍一下,与大家分享. 互联网现有工具 基于网页分析工具: 1.       阿里测 ...

  4. 吴裕雄 实战PYTHON编程(8)

    import pandas as pd df = pd.DataFrame( {"林大明":[65,92,78,83,70], "陈聪明":[90,72,76, ...

  5. 数据预处理之独热编码(One-Hot Encoding)(转载)

    问题由来 在很多机器学习任务中,特征并不总是连续值,而有可能是分类值. 例如,考虑一下的三个特征: ["male", "female"] ["from ...

  6. HTML的基础知识

    1.什么是HTML? html是一种,用来描述网页的一种语言,指的是一种超文本编辑语言,他不是一种编程的语言,而是一种标记的语言,包含:静态HTML和动态的HTML: 2.学习推荐的网站: http: ...

  7. Hibernate 序列生成主键

    @Entity @Table(name="TABLE_NAME") public class TableName implements Serializable { @Id @Ge ...

  8. 如何禁止浏览器自动填充非登陆input的账号和密码?

    发现浏览器填充密码的方式,那就是,找到页面上第一个type为password的input填充.发现了这个规律后,很自然的就想到了,是不是可以在真正的password前面加一个隐藏的password,形 ...

  9. 【校招面试 之 C/C++】第3题 为什么要内存对齐?以及内存对齐的方式

    1.为什么要进行内存对? 参考:https://blog.csdn.net/a369000753/article/details/51188915 所谓内存对齐,是为了让内存存取更有效率而采用的一种编 ...

  10. JSP的内置对象application、session、request、page的作用域

    1.application内置对象的类型名称为ServletContext. 2.session内置对象的类型名称为HttpSession. 3.application作用域:对应整个应用上下文. a ...