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. easyui input未设id导致的问题

    今天又踩了一个坑,大致是没有给input设id,使用类选择器绑定easyui控件,然后使用name设值,现在值设进去后界面没有显示. 做的界面部分截图如图: 点击下面两个橙色的按钮,通过调用下面的方法 ...

  2. Resume (Curriculum Vitae)

    The resume (Curriculum Vitae) is a selling tool outlining your skills and experience so an employer ...

  3. overflow: scroll

    overflow: scroll在安卓5.0的情况下,不论内容是否填满屏幕,都会强制解析出滚动条,所以最好是使用overflow: auto

  4. IIS PHP Warning: Unknown: open(c:\\php\\tmp\\sess_xxx, O_RDWR) failed: Permission denied (13) in Unknown on line 0

    出现这个问题的原因是你修改了php保存session的路径,但没有给用户访问该目录的权限.   右键该目录,给users用户组读.写的权限.

  5. Combobox实现多项选择 Silverlight下“Combobox”怎样实现多项选择?

    把 combobox里面的项换成checkedbox 示例: combobox cbb=new combobox(); ) { CheckBox cb = new CheckBox(); cb.Com ...

  6. Golang之时间格式化,计时器

    地鼠敲下一堆代码,记录着当天的时间 package main import ( "fmt" "time" ) func getTime() { now := t ...

  7. 品味性能之道<十>:Oracle Hint

    Hint 是Oracle 提供的一种SQL语法,它允许用户在SQL语句中插入相关的语法,从而影响SQL的执行方式. 因为Hint的特殊作用,所以对于开发人员不应该在代码中使用它,Hint 更像是Ora ...

  8. g++报错原因分析:expected class-name before ‘{’ token

    今天写程序的时候, 遇到这样一个错误expected class-name before ‘{’ token 最后发现原来是我的头文件声明没有加. 继承时不要忘记加基类的头文件 错误: class F ...

  9. Speeding up Homestead on Windows Using NFS

    Speeding up Homestead on Windows Using NFS Sep 07 2015 Homestead Laravel EDIT: I have another articl ...

  10. oracle常用函数速记

    1.截断中文字符串 CREATE OR REPLACE function cn_cutstr(v_str varchar2,v_len number) return varchar2 IS v_i n ...