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. JAVA 打印流与转换流

    转换流主要有两个 InputStreamReader 和 OutputStreamWriter 1. InputStreamReader 主要是将字节流输入流转换成字符输入流 2. OutputStr ...

  2. Game2048

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. 奶牛易物小组 Alpha冲刺

    项目地址:https://gitee.com/rrycbar/NenuChange 1 第一天 日期:2018/6/14 1.1 今日完成任务情况以及遇到的问题. 吴建瑜: 完成任务: 1.继续完善购 ...

  4. oracle查询锁表

    select b.username,b.sid,b.serial#,logon_time from v$locked_object a,v$session b where a.session_id = ...

  5. Java的三种多线程

    项目结构 继承Thread类 /* * Thread类实现了Runnable接口 */ public class MyThread extends Thread { @Override public ...

  6. Laravel框架中实现supervisor执行异步进程

    问题描述:在使用Laravel框架实现动态网页时,若有些操作计算量较大,为了不影响用户体验,往往需要使用异步方式去处理.这里使用supervisor和laravel自带的queues实现. Super ...

  7. OSGi 系列(十四)之 Event Admin Service

    OSGi 系列(十四)之 Event Admin Service OSGi 的 Event Admin 服务规范提供了开发者基于发布/订阅模型,通过事件机制实现 Bundle 间协作的标准通讯方式. ...

  8. 一次HBase问题的解决过程(Status: INCONSISTENT)

    ==版本信息== HBase:2.7.1 Storm:1.0.1 RocketMQ:3.4.6(阿里版) ==问题描述== 2018年9月3号晚上23点左右,例行巡检系统运行状况时, 发现Storm消 ...

  9. anaconda 设置新的环境,这样python的包随便换和安装

    1.进入anaconda navigate 里面创建一个新的environment 2.cmd里面conda info -e 3.activate 环境名 然后python的包就已经换到新环境了

  10. 多线程的使用:只能用cmd来玩不能用idle

    from multiprocessing import Process import os def pro_do(name, func): print () if __name__ == " ...