博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2396 Budget(有上下限的最大流)
阅读量:5825 次
发布时间:2019-06-18

本文共 3141 字,大约阅读时间需要 10 分钟。

题目链接:

题意:输入的第一行是测试数据的个数。每组测试数据的第一行是N和M。第二行是N个数,表示N行的和,第三行是M个数,表示M列的和。接下来一个K,表示有以下K个限制,每个限制的形式X Y Z W,其中Z是< > 或者=,表示第X行第Y列的元素和W的大小关系。假如Z是>,那么说明第X行第Y列的元素必须大于W。如果X是0,意思指所有第Y列的数和W的大小关系;如果Y是0,意思指所有第X行的数和W的大小关系;如果X和Y均为0,则表示整个矩阵和W的大小关系。如果有满足所有条件的矩阵,输出;没有的话,输出IMPOSSIBLE。

思路:上下限最大流。

#include 
#include
#include
#define MAX 230#define min(x,y) ((x)<(y)?(x):(y))#define max(x,y) ((x)>(y)?(x):(y))using namespace std;const int INF=1000000000;int high[MAX][MAX],low[MAX][MAX];int cap[MAX][MAX];int in[MAX],out[MAX],inc[MAX],pre[MAX],visit[MAX];int n,m,s,t,ss,tt,sum;int r[MAX],c[MAX];void InPut(){ int i,j,num,u,v,w; char ch; memset(high,0,sizeof(high)); memset(low,0,sizeof(low)); scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&r[i]); for(i=1;i<=m;i++) scanf("%d",&c[i]); for(i=1;i<=n;i++)for(j=1;j<=m;j++) high[i][j+n]=INF; for(scanf("%d",&num);num--;) { scanf("%d%d %c%d",&u,&v,&ch,&w); if(u==0&&v!=0) { if(ch=='=')for(i=1;i<=n;i++)low[i][v+n]=high[i][v+n]=w; else if(ch=='<')for(i=1;i<=n;i++)high[i][v+n]=min(high[i][v+n],w-1); else for(i=1;i<=n;i++)low[i][v+n]=max(low[i][v+n],w+1); } else if(u!=0&&v==0) { if(ch=='=')for(i=1;i<=m;i++)low[u][i+n]=high[u][i+n]=w; else if(ch=='<')for(i=1;i<=m;i++)high[u][i+n]=min(high[u][i+n],w-1); else for(i=1;i<=m;i++)low[u][i+n]=max(low[u][i+n],w+1); } else if(u==0&&v==0) { for(i=1;i<=n;i++)for(j=1;j<=m;j++) { if(ch=='=') low[i][j+n]=high[i][j+n]=w; else if(ch=='<')high[i][j+n]=min(high[i][j+n],w-1); else low[i][j+n]=max(low[i][j+n],w+1); } } else { if(ch=='=')low[u][v+n]=high[u][v+n]=w; else if(ch=='<')high[u][v+n]=min(high[u][v+n],w-1); else low[u][v+n]=max(low[u][v+n],w+1); } } s=0;t=n+m+1; for(i=1;i<=n;i++)low[s][i]=high[s][i]=r[i]; for(i=1;i<=m;i++)low[i+n][t]=high[i+n][t]=c[i];}int BFS(int s,int t){ int i,u; queue
Q; memset(pre,-1,sizeof(pre)); memset(visit,0,sizeof(visit)); Q.push(s);visit[s]=1;inc[s]=INF; while(!Q.empty()) { u=Q.front(); Q.pop(); for(i=0;i<=t;i++) if(!visit[i]&&cap[u][i]) { inc[i]=min(inc[u],cap[u][i]); pre[i]=u; visit[i]=1; if(i==t) return 1; Q.push(i); } } return 0;}int Maxflow(int s,int t){ int maxflow=0,i; memset(inc,0,sizeof(inc)); while(BFS(s,t)) { maxflow+=inc[t]; for(i=t;i!=s;i=pre[i]) { cap[pre[i]][i]-=inc[t]; cap[i][pre[i]]+=inc[t]; } } return maxflow;}int limitMaxflow(){ int i,j,ans; memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(cap,0,sizeof(cap)); for(sum=0,i=0;i<=t;i++) for(j=0;j<=t;j++) { cap[i][j]=high[i][j]-low[i][j]; out[i]+=low[i][j]; in[j]+=low[i][j]; sum+=low[i][j]; } for(ss=t+1,tt=t+2,i=0;i<=t;i++) cap[ss][i]=in[i],cap[i][tt]=out[i]; cap[t][s]=INF; ans=Maxflow(ss,tt); if(ans!=sum) return 0; cap[t][s]=cap[s][t]=0; ans=Maxflow(s,t); return 1;}int C;int main(){ for(scanf("%d",&C);C--;) { InPut(); if(!limitMaxflow()) { puts("IMPOSSIBLE"); continue; } int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) printf("%d ",cap[j+n][i]+low[i][j+n]); printf("\n"); } } return 0;}

  

转载地址:http://mksdx.baihongyu.com/

你可能感兴趣的文章
fadingEdge
查看>>
hello world
查看>>
php 文件操作
查看>>
Python开发(基础):列表List
查看>>
支付宝SDK官方下载-移动端、服务端各个平台通用
查看>>
Apache的prefork模式和worker模式
查看>>
使用电子授权进行软件保护
查看>>
maven 3.3.3 关于jdk报错的问题
查看>>
快速编写接口api规范文档工具(Markdown)
查看>>
Linux Svn 使用
查看>>
鸟哥LINUX的推荐网站
查看>>
Java序列化
查看>>
Cacti流量监控系统搭建维护手册
查看>>
redis主从+sentinel
查看>>
MongoDB基本使用
查看>>
解决IE7下块级元素随着滚动条滚动而滚动的问题
查看>>
Tomcat 重启脚本 restart.sh
查看>>
我的友情链接
查看>>
Lenovo B460无法搜索无线的解决方法
查看>>
easyui datagrid local pager 表格本地分页
查看>>