hdu 4888 最大流慢板
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 最大流慢板的更多相关文章
- hdu 4888 最大流给出行列和求矩阵
第一步,考虑如何求是否有解.使用网络流求解,每一行和每一列分别对应一个点,加上源点和汇点一共有N+M+2个点.有三类边: 1. 源点 -> 每一行对应的点,流量限制为该行的和 2. 每一行对应的 ...
- 2014联合三所学校 (HDU 4888 HDU 4891 HDU 4893)
HDU 4891 The Great Pan 注册标题 他怎么说,你怎么样 需要注意的是乘法时,它会爆炸int 代码: #include<iostream> #include<c ...
- HDU 1532 最大流入门
1.HDU 1532 最大流入门,n个n条边,求第1点到第m点的最大流.只用EK做了一下. #include<bits/stdc++.h> using namespace std; #pr ...
- hdu 4888 Redraw Beautiful Drawings(最大流,判环)
pid=4888">http://acm.hdu.edu.cn/showproblem.php?pid=4888 加入一个源点与汇点,建图例如以下: 1. 源点 -> 每一行相应 ...
- HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
Problem Description Alice and Bob are playing together. Alice is crazy about art and she has visited ...
- hdu 4888 Redraw Beautiful Drawings 最大流
好难好难,将行列当成X和Y,源汇点连接各自的X,Y集,容量为行列的和,相当于从源点流向每一行,然后分配流量给每一列,最后流入汇点,这样执意要推断最后是否满流,就知道有没有解,而解就是每一行流向每一列多 ...
- hdu 4289 最大流拆点
大致题意: 给出一个又n个点,m条边组成的无向图.给出两个点s,t.对于图中的每个点,去掉这个点都需要一定的花费.求至少多少花费才能使得s和t之间不连通. 大致思路: 最基础的拆点最大 ...
- Going Home HDU - 1533 费用流
http://acm.hdu.edu.cn/showproblem.php?pid=1533 给一个网格图,每两个点之间的匹配花费为其曼哈顿距离,问给每个的"$m$"匹配到一个&q ...
- hdu 4975 最大流快版
http://acm.hdu.edu.cn/showproblem.php?pid=4975 给出每行每列的和,问是否存在这样的表格:每个小格放的数字只能是0--9. 直接用第八场最大流模板. #in ...
随机推荐
- ArcGIS模型构建器案例学习笔记-字段处理模型集
ArcGIS模型构建器案例学习笔记-字段处理模型集 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 由四个子模型组成 子模型1:判断字段是否存在 方法:python工 ...
- 基元线程同步构造之信号量(Semaphore)
信号量(semaphore)不过是由内核维护的 int32变量而已,(说通俗点就是好比一个线程容器里面允许执行的线程数,0计数就是允许执行的0个线程数,1就是允许执行的1个线程数,2就是允许执行的2个 ...
- triton,docker,mesos
triton user: jill /root/.sdc/docker/jill 下 root@1f6af9d8-8ed9-e940-9c6c-d9505ca25896:~/.sdc/docker/j ...
- yum 操作
一.使用yum安装和卸载软件,有个前提是yum安装的软件包都是rpm格式的. 安装的命令是,yum install ~,yum会查询数据库,有无这一软件包,如果有,则检查其依赖冲突关系,如果没有依赖冲 ...
- cmd 获取 拖拽文件名
1. @echo off & setlocal enableDelayedExpansion set a= set /p a=Please drag your txt file for spl ...
- Retrofit2.0+RxJava2.0问题
问题1:java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path ...
- EasyUI 修改
<script type="text/javascript"> <!-- js --> /*=============================修改对 ...
- ORDER BY 子句在视 图、内联函数、派生表、子查询和公用表表达式中无效
SQL语句: select * from (select distinct t2.issue,cashmoney from (select distinct issue from lot_gamepa ...
- Java集合set的并、交、差操作
集合的并.交.差操作 Set<Integer> result = new HashSet<Integer>(); Set<Integer> set1 = new H ...
- Infinity,NaN
常量 说明 Infinity 表示正无穷大的特殊值. -Infinity 表示负无穷大的特殊值. NaN Number 数据类型的一个特殊成员,用来表示“非数字”(NaN) 值. undefined ...