hdu 4888 最大流慢板
来源:互联网 发布:知乎 大胸妹子 编辑:程序博客网 时间:2024/06/12 01:31
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;}
0 0
- hdu 4888 最大流慢板
- HDU 4888/4975 最大流
- hdu 4888 Redraw Beautiful Drawings(最大流)
- hdu 4888 Redraw Beautiful Drawings 最大流
- hdu 4888 Redraw Beautiful Drawings(最大流)
- HDU 4888 Redraw Beautiful Drawings(最大流)
- HDU 4888 最大流+判环
- hdu 2883(最大流)
- 【最大流】HDU 3572
- hdu 2883 最大流
- hdu 3572最大流
- hdu 3605 最大流
- HDU 1733 最大流
- hdu 3549 最大流
- hdu 2732 最大流
- hdu 3605 (最大流)
- hdu 2883 (最大流)
- hdu 3081 (最大流)
- 【一些题】一些重要函数的实现
- 从零开始学android<Bitmap图形组件.四十七.>
- POJ2478 Farey Sequence【快速求欧拉函数】
- 黑马程序员——高新技术3——反射和JavaBean
- leetcode minimum depth(binary tree)
- hdu 4888 最大流慢板
- leetcode Rotate Image
- DocumentHelper xml工具包
- 程序员练级攻略
- 网络解析1——TCP滑动窗口机制解释1
- 系统原理分析架构-三--代理服务器简介及分类
- HTTP与HTTPS
- 使用TCmalloc的堆栈检查
- android Theme使用总结