网络流不难写,难的建一个能解决问题的模型。。

即使我知道这是网络流专题的题目,也绝不会能想出这种解法,=_=||

题意:

给出一个矩阵的 前i行和 以及 前i列和,然后找到一个满足要求的矩阵,而且每个元素在1~20之间。

分析:

先求出每行的元素和A'i    每列的元素和B'i

紫书上说建一个二分图,每行是一个X节点,每列代表一个Y节点。

因为流量最小是0,而题中说元素大小在1~20之间,所以我们先将每个元素都减一。

这样每行的元素和就变成了A'i-C,每列之和变为B'i-R

XY之间每条边的容量为19

源点到X中每个点的容量为A'i-C,Y中的每个点到汇点的容量为B'i-R。当所有从源点出发和在汇点结束的边满载时有解。

“为什么这样做是对的呢?请读者思考。”

好吧,那我就思考。Xi->Yj这条边就对应矩阵中第i行第j列元素的值,而且所有从X出发的边,汇聚到Yj的总流量就是第j列的和。

反过来,从Xi出发的总流量就是第i行的和,分流到各个Y中。

 #include <bits/stdc++.h>

 using namespace std;

 const int maxn =  + ;
const int INF = ; struct Edge
{
int from, to, cap, flow;
Edge(int u=, int v=, int c=, int f=): from(u), to(v), cap(c), flow(f) {}
}; struct EdmondsKarp
{
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int a[maxn];
int p[maxn]; void Init(int n)
{
for(int i = ; i < n; ++i) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, ));
edges.push_back(Edge(to, from, , ));
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} int MaxFlow(int s, int t)
{
int flow = ;
for(;;)
{
memset(a, , sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = INF;
while(!Q.empty())
{
int x = Q.front(); Q.pop();
for(int i = ; i < G[x].size(); ++i)
{
Edge& e = edges[G[x][i]];
if(!a[e.to] && e.cap > e.flow)
{
a[e.to] = min(a[x], e.cap - e.flow);
p[e.to] = G[x][i];
Q.push(e.to);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int u = t; u != s; u = edges[p[u]].from)
{
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
}
flow += a[t];
}
return flow;
}
}; EdmondsKarp g;
int ind[maxn][maxn];//ind[i][j]记录第i行第j列对应的边的编号 int main()
{
//freopen("in.txt", "r", stdin); int T, R, C;
scanf("%d", &T);
for(int kase = ; kase <= T; ++kase)
{
scanf("%d%d", &R, &C);
g.Init(R+C+);
int cur, last = ;
for(int i = ; i <= R; ++i)
{//第i行的节点标号为i,源点标号为0
scanf("%d", &cur);
g.AddEdge(, i, cur - last - C);
last = cur;
}
last = ;
for(int i = ; i <= C; ++i)
{//第i列的标号为R+i,汇点标号为R+C+1
scanf("%d", &cur);
g.AddEdge(R+i, R+C+, cur - last - R);
last = cur;
}
for(int i = ; i <= R; ++i)
for(int j = ; j <= C; ++j)
{
g.AddEdge(i, j+R, );
ind[i][j] = g.edges.size() - ;//因为AddEdge中还有一条反向边,所以是-2
}
g.MaxFlow(, R+C+); printf("Matrix %d\n", kase);
for(int i = ; i <= R; ++i)
{
printf("%d", g.edges[ind[i][]].flow + );
for(int j = ; j <= C; ++j)
printf(" %d", g.edges[ind[i][j]].flow + );
printf("\n");
}
printf("\n");
} return ;
}

代码君

UVa 11082 (网络流建模) Matrix Decompressing的更多相关文章

  1. UVA 11082 矩阵解压(网络流建模)

    矩阵解压 紫书P374 建模真的是挺难的,如果直接给我这题,我是想不到用网络流的,所以还应多做网路流建模,学会如何转化成网络流 还有,现在用的EK算法是比较慢的,还应去看看Dnic和ISAP,并且理解 ...

  2. UVa 11082 Matrix Decompressing(最大流)

    不想吐槽了..sample input 和sample output 完全对不上...调了一个晚上...不想说什么了... -------------------------------------- ...

  3. UVA - 11082 Matrix Decompressing

    2. B - Matrix Decompressing 题意:定义一个R*C的正整数矩阵(1<=R,C<=20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和. 题目已知R,C和数 ...

  4. uva Matrix Decompressing (行列模型)

    Matrix Decompressing 题目:    给出一个矩阵的前i行,前j列的和.要求你求出满足的矩阵. 矩阵的数范围在[1,20].   一開始就坑在了这里.没读细致题目. 囧...   事 ...

  5. UVA11082 Matrix Decompressing 最大流建模解矩阵,经典

    /** 题目:UVA11082 Matrix Decompressing 链接:https://vjudge.net/problem/UVA-11082 题意:lrj入门经典P374 已知一个矩阵的行 ...

  6. UVa 11082 & 最大流的行列模型

    题意: 给出一个矩阵前i行的和与前j列的和,(i∈[1,r],j属于[1,c]),每个元素ai,j∈[1,20],请你还原出这个矩阵,保证有解. SOL: 给网络流建模跪了,神一样的建图,如果我我会怎 ...

  7. UVA 11149 - Power of Matrix(矩阵乘法)

    UVA 11149 - Power of Matrix 题目链接 题意:给定一个n*n的矩阵A和k,求∑kiAi 思路:利用倍增去搞.∑kiAi=(1+Ak/2)∑k/2iAi,不断二分就可以 代码: ...

  8. 培训补坑(day4:网络流建模与二分图匹配)

    补坑时间到QAQ 好吧今天讲的是网络流建模与二分图匹配... day3的网络流建模好像说的差不多了.(囧) 那就接着补点吧.. 既然昨天讲了建图思想,那今天就讲讲网络流最重要的技巧:拆点. 拆点,顾名 ...

  9. UVA-11082 Matrix Decompressing(有上下界的最大流)

    题目链接: Matrix Decompressing 题意: 给一个矩阵的每行和每列的和,(给的是前i行或者列的和); 矩阵中每个元素的值在1到20之间,找出这样的一个矩阵: 思路: 把它转化成一个二 ...

随机推荐

  1. php header函数要点

    发布:snowfly   来源:网络     [大 中 小] 相信很多人写程序时,使用 header(location) 进行跳转往往不记得写 exit() 语句,这种做法存在严重风险. 从浏览器来看 ...

  2. ubuntu 安装dell无线网卡2

    以下转自:http://blog.sina.com.cn/s/blog_73b6331101016haq.html ubuntu 12.04 bcm43xx无线网卡安装记录 (2012-07-01 0 ...

  3. WPF处理Windows消息

    WPF中处理消息首先要获取窗口句柄,创建HwndSource对象 通过HwndSource对象添加消息处理回调函数. HwndSource类: 实现其自己的窗口过程. 创建窗口之后使用 AddHook ...

  4. 浅谈string

    #include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 using std::string;using ...

  5. 关于分区技术的索引 index

    关于分区技术---索引 Index 一.   分区索引分类: 本地前缀分区索引(local prefixedpartitioned index) 全局分区索引(global partitionedin ...

  6. C# 白话系列之——白话委托

    今天看到首页有个委托的文章,但大都写的太专业,而且没有实用的例子场景.正好昨天做了一个有关委托的功能,所以也来凑个热闹,用白话掰掰 一.委托是什么 我们都知道数据类型,简单点的如,想给一个变量赋值整数 ...

  7. Java 动态代理(转载)

    JAVA的动态代理  代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后 处理消息等.代理类与 ...

  8. VC++入门精通视频教程

    1.1.Windows程序运行原理-1 上传日期:2012-03-19 09:18:50  相关摘要:  - 在关闭一个windows窗口时,也关闭另一个吗 - 对纯面向对象的PHP程序有何看法? - ...

  9. UIImageView加抖动效果(转)

    CGAffineTransform moveRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 20, 0); CGAffine ...

  10. Jplayer(转)

    Jplayer必须要加载 1.样式  jplayer.blue.monday.css 2.jq jquery.1.6.2.min.js 当前最新版本为1.6.2 3.jplayer的js jquery ...