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 ...
随机推荐
- Hibernate 的事物简单的增删查改
Hibernate 是一个优秀的ORM框架体现在: 1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象.建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管 ...
- struts2 参数注入 方法拦截器
web.xml: <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi=" ...
- zset
zset sorted set,有序集合 元素为string类型 元素具有唯一性,不重复 每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序 说明:没有修改操作 增 ...
- mysql允许远程登录
Mysql为了安全性,在默认情况下用户只允许在本地登录,可是在有此情况下,还是需要使用用户进行远程连接,因此为了使其可以远程需要进行如下操作: 一.允许root用户在任何地方进行远程登录,并具有所有库 ...
- Python+Webdriver,中文前加u是unicode格式编码的意思
Python+Webdriver写脚本时,对一些输入框赋值会涉及到输入中文,这时需要在中文前加u 举个例子,在用百度搜索时,要在搜索输入框内输入值, 我用的编码格式是utf-8,向输入框内输入值是:d ...
- Ubuntu中解决机箱前置耳机没声音
Ubuntu中解决机箱前置耳机没声音 安装pavucontrol软件: sudo apt-get install pavucontrol 然后直接运行pavucontrol打开软件: 将输出设备设置为 ...
- 在Objc项目中调用Swift
之前的文字中记录了在Swift项目中调用OC的相关代码,比较简单直接 传送门 但是在OC中调用swift代码则不是那么的和谐,网络上很多文章业已经有点陈旧.记录步骤如下: 1.创建OC项目 (1)启动 ...
- git 常用命令笔记
#提交代码会加上用户名和邮箱 git config --global user.name 名字 git config --global user.email 邮箱 git config --globa ...
- Error writing temporary file. Make sure your temp folder is valid
NSIS Error:Error writing temporary file. Make sure your temp folder is valid的解决 老婆用了自己的WIN7系统一段时 ...
- POJ 1122.FDNY to the Rescue! Dijkstra
FDNY to the Rescue! Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2808 Accepted: 86 ...