UVa 11082 - 最大流 基础建模

来源:互联网 发布:dht网络bt 编辑:程序博客网 时间:2024/05/23 01:17

一道很基础的网络流建模。。

本题输入的是前缀和,先用它们求出每行、每列的元素和

然后将每一行看作一个节点(记作Xi),每一列看作一个节点(记作Yi),并新增源点S、汇点T。

S往Xi连边,容量为这一行的元素和减1;

Yi往T连边,容量同上。

每个Xi往每个Yj连边,容量为20-1=19。

之所以要将容量都减1,是因为边权要在1~20之间,有下界,但并不需要用到专门的有下界最大流算法,可以直接先减1,求出结果后再加1。

跑一遍最大流。当且仅当所有S出边和T入边都满载时有解。元素Aij的值即为Xi -> Yj的流量+1。

模板用的是Rujia Liu的。。可读性很强,但效率不是很高。。下次把黄学长的模板学过来。。

(最近刷题速度下降。。再这样下去药丸。。

// UVa11082#include <cstdio>#include <algorithm>#include <cstring>using namespace std; const int M=2000, N=100, INF=0x3f3f3f3f; #define rep(i,a,b) for (int i=a; i<=b; i++) #define read(x) scanf("%d", &x) struct Edge{ int from, to, pre, cap, flow; }e[M]; int p, pre[N]; void ine(int from, int to, int cap, int flow) { e[p].from=from; e[p].to=to; e[p].cap=cap; e[p].pre=pre[from]; e[p].flow=flow; pre[from]=p; p++; } #define reg(i,x) for (int i=pre[x]; i!=-1; i=e[i].pre) void Add_Edge(int from, int to, int cap) { ine(from, to, cap, 0); ine(to, from, 0, 0); } int n, m, s, t, a[N], last, tot, edges, nodes, id[N][N], kase=0, T, cur[N], d[N]; bool vis[N]; void init() { p=0; rep(i,1,edges) e[i].pre=-1; rep(i,1,nodes) pre[i]=-1; } int Q[2*N]; bool BFS() { memset(vis, 0, sizeof(vis)); int head=1, tail=1; Q[1]=s; d[s]=0; vis[s]=true; while (head<=tail) { int x=Q[head++]; reg(i,x) { int y=e[i].to; if (!vis[y] && e[i].cap>e[i].flow) { vis[y]=true; d[y]=d[x]+1; Q[++tail]=y; } } } return vis[t]; } int DFS(int x, int a) {  // a表示“目前为止所有弧的最小残量” if (x==t || a==0) return a; int flow=0, f; for (int &i=cur[x]; i!=-1; i=e[i].pre) { if (d[x]+1==d[e[i].to] && (f=DFS(e[i].to, min(a, e[i].cap-e[i].flow)))>0) { flow+=f; a-=f;  // Why can we do this? e[i].flow+=f; e[i^1].flow-=f; if (a==0) break; } } return flow; } void Dinic() { int flow=0; while (BFS()) { rep(i,1,n+m+2) cur[i]=pre[i]; flow+=DFS(s, INF); } }int main(){read(T);while (T--) {read(n); read(m);edges=n*m*2+n+m+5;nodes=n+m+5;init();read(tot); a[1]=tot;rep(i,2,n) last=tot, read(tot), a[i]=tot-last;read(tot); a[n+1]=tot;rep(i,n+2,n+m) last=tot, read(tot), a[i]=tot-last;s=n+m+1, t=n+m+2;rep(i,1,n) Add_Edge(s, i, a[i]-m);rep(i,n+1,m+n) Add_Edge(i, t, a[i]-n);rep(i,1,n)   rep(j,n+1,n+m) {    Add_Edge(i, j, 19);    id[i][j]=p-2;  }Dinic();printf("Matrix %d\n", ++kase);rep(i,1,n) {  rep(j,n+1,n+m)  printf("%d ", e[id[i][j]].flow+1);  puts("");}puts("");}return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 公司依旷工理由辞退我该怎么办 试工两天被辞退了不发工资怎么办 员工在单位被打监控调不出来怎么办 老师罚做60张试卷家长该怎么办 孩子在幼儿园被老师打该怎么办 孩子被孩子打了老师该怎么办? 法院判决书下来后看守所不收怎么办 因病看守所不收押发院判了怎么办 现在显示还在看守所羁押需要怎么办 嫖了N多年丈夫让我怎么办 预约考试的登录密码忘了怎么办 人进了看守所信用卡没还怎么办 上海租房人放2个麻将台怎么办 南宁公租房住满5年后怎么办 合伙买房时如果出售意见不合怎么办 老旧小区改造下水一楼不同意怎么办 老旧小区下水改造没改怎么办 替公司租房子中介不退押金怎么办 想在昆山找合租房的该怎么办 链家二手房价钱买贵了怎么办 拿私人房产证抵押借钱不还怎么办 在借贷宝里借钱不还怎么办 出租屋的大门感应钥匙弄丢了怎么办 法院拍卖的房子房主不配合怎么办 租的房子如果房主卖了怎么办 房东把门锁换了里面的东西怎么办 房租没到期房东把门锁换了怎么办 租了三年店面房东违反了合同怎么办 学生登录教务系统的密码忘记怎么办 铜陵无牌助力车被交警查到怎么办 福州超标电动车被交警抓到怎么办 单位自管公租房承租人去世怎么办 取得房产证后贷款批不下来怎么办 租店面遇到难搞的房东怎么办 在拆违通知书上签字了该怎么办 单位没交公职金的退休后怎么办 公租房合同到期后没有续签怎么办 租房合同没到期不想租了怎么办 租的房子是人家公租房怎么办 五险合一软件口令忘记了怎么办 计生办把婚育状况登记错了怎么办?