题意:

  给出一个矩阵前i行的和与前j列的和,(i∈[1,r],j属于[1,c]),每个元素ai,j∈[1,20],请你还原出这个矩阵,保证有解.

SOL:

  给网络流建模跪了,神一样的建图,如果我我会怎么做呢?...搜索?然而每个元素具有行,列双重相关性...暴力都打不出来吧...

  然而我们顺着搜索的方向想,如果每个点的搜索值最终小于这行的和,那么我们应该做什么?增大它!是不是感觉有点增广的想法出来了------>然而我只是瞎BB...事后觉得可以这么想但考场上并不能这么想出来...

  考虑它的建图,因为每个元素至少为1,即流量至少为1,那它就变成一个有上下界的网络流问题...不会怎么办?因为每个元素都大于等于1那么我们把他都减一!

  我们对每一行的和对应一个点与超级源S相连,容量为这一行的和,对于每条列我们建一个点与汇点相连,容量为列的和,然后行与列的点两两相连,容量为19,也就是数的最大值,然后跑一遍最大流,行与列之间每条边的流量就是原矩阵中的元素.

  如何证明它的正确性?

  显然所有行与列的和是相等的,即源汇的出入边一定都满流,同时,我们可以把每一行与所有列的连边上的流量看做该行对此列所做的"贡献",因为最大流一定使源汇出入边满流,所以一定有一种方案.那么这个显然是正确的.

  发现行与列的关系以及和的限制条件,也许是思路突破的关键吧.

  

  警报!警报!警报!!

    自己打的代码莫名TLE了...因为点不多所以老人家写的EK,然而我写的dinic居然TLE了?smg?...因为时间不多先贴上代码,以后有空回来看...模型是关健啊.

 TLE代码:

  

/*==========================================================================
# Last modified: 2016-03-08 08:03
# Filename: uva11082.cpp
# Description:
==========================================================================*/
#define me AcrossTheSky
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector> #define lowbit(x) (x)&(-x)
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1] #define maxn 1000
#define maxm 1000000
#define pi 3.1415926535898
#define _e 2.718281828459
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull; template<class T> inline
void read(T& num) {
bool start=false,neg=false;
char c;
num=0;
while((c=getchar())!=EOF) {
if(c=='-') start=neg=true;
else if(c>='0' && c<='9') {
start=true;
num=num*10+c-'0';
} else if(start) break;
}
if(neg) num=-num;
}
/*==================split line==================*/
struct Edge{
int from,to,cap,v;
}e[maxm];
int r,c;
int id[maxn][maxn],a[maxn],b[maxn];
int first[maxn],next[maxm],cur[maxn],d[maxn];
bool vis[maxn];
int sume=1,n,S,T;
void addedge(int x,int y,int cap){
sume++; e[sume].from=x; e[sume].to=y; e[sume].cap=cap;
next[sume]=first[x]; first[x]=sume; id[x][y]=sume;
sume++; e[sume].from=y; e[sume].to=x; e[sume].cap=0;
next[sume]=first[y]; first[y]=sume; id[y][x]=sume;
}
void reset(){
sume=1;
a[0]=b[0]=0;
memset(e,0,sizeof(e));
memset(next,0,sizeof(next));
memset(first,0,sizeof(first));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
//T=maxn-10,S=0;
}
bool bfs(){
queue<int>q;
FORP(i,S,T) d[i]=INF;
//memset(vis,false,sizeof(vis));
q.push(S); d[S]=0; //vis[S]=true;
while (!q.empty()){
int now=q.front(); q.pop();
for (int i=first[now];i;i=next[i])
if (d[e[i].to]==INF && e[i].cap){
d[e[i].to]=d[now]+1;
//vis[e[i].to]=true;
q.push(e[i].to);
}
}
return d[T]<INF;
}
int dfs(int now,int a){
if (now==T || !a) return a;
int f,flow=0;
for (int &i=cur[now];i;i=next[i])
if (d[now]+1==d[e[i].to] && (f=dfs(e[i].to,min(a,e[i].cap)))>0){
flow+=f; a-=f; e[i].cap-=f; e[i].v+=f; e[i^1].cap+=f;
if (!a) break;
}
return flow;
}
void dinic(){
int flow=0;
while (bfs()){
FORP(i,0,n) cur[i]=first[i];
flow+=dfs(S,INF);
}
}
int main(){
int cas; read(cas); //int cass=1;
FORP(cass,1,cas){
reset();
scanf("%d%d",&r,&c);
n=r+c+1; S=0; T=r+c+4;
FORP(i,1,r) scanf("%d",&a[i]);//read(a[i]);
FORP(i,1,c) scanf("%d",&b[i]);//read(b[i]);
FORP(i,1,r) addedge(0,i,a[i]-a[i-1]-c);
FORP(i,1,r)
FORP(j,r+1,r+c+1) addedge(i,j,19);
FORP(j,r+1,r+c+1) addedge(j,T,b[j-r]-b[j-r-1]-r);
printf("Matrix %d\n",cass); //cass++;
dinic();
FORP(i,1,r)
FORP(j,1,c)
printf("%d%c",e[id[i][j+r]].v+1,(j==c)?'\n':' ');
if (cas) cout << endl;
}
}

lrj代码:

  

// UVa11082 Matrix Decompressing
// Rujia Liu
// Slower version with EdmondsKarp
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std; const int maxn = 50 + 5;
const int INF = 1000000000; 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]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
int a[maxn]; // 当起点到i的可改进量
int p[maxn]; // 最短路树上p的入弧编号 void init(int n) {
for(int i = 0; i < n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap) {
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, 0, 0));
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
} int Maxflow(int s, int t) {
int flow = 0;
for(;;) {
memset(a, 0, sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = INF;
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i = 0; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(!a[e.to] && e.cap > e.flow) {
p[e.to] = G[x][i];
a[e.to] = min(a[x], e.cap-e.flow);
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]^1].flow -= a[t];
}
flow += a[t];
}
return flow;
}
}; EdmondsKarp g;
int no[maxn][maxn]; int main() {
int T, R, C, v, kase = 0;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++) {
scanf("%d%d", &R, &C);
g.init(R+C+2);
int last = 0;
for(int i = 1; i <= R; i++) {
scanf("%d", &v);
g.AddEdge(0, i, v - last - C); // row sum is v - last
last = v;
}
last = 0;
for(int i = 1; i <= C; i++) {
scanf("%d", &v);
g.AddEdge(R+i, R+C+1, v - last - R); // col sum is v - last
last = v;
}
for(int i = 1; i <= R; i++)
for(int j = 1; j <= C; j++) {
g.AddEdge(i, R+j, 19);
no[i][j] = g.edges.size() - 2; // no[i][j] is the index of arc for cell(i,j)
}
g.Maxflow(0, R+C+1); printf("Matrix %d\n", kase);
for(int i = 1; i <= R; i++) {
for(int j = 1; j <= C; j++)
printf("%d ", g.edges[no[i][j]].flow + 1); // we subtracted 1 from every cell
printf("\n");
}
printf("\n");
}
return 0;
}

UVa 11082 & 最大流的行列模型的更多相关文章

  1. UVA - 11082 Matrix Decompressing(最大流+行列模型)

    题目大意:给出一个R行C列的矩阵,如今给出他的前1-R行和 && 前1-C列和,问这个矩阵原来是如何的,要求每一个元素大小在1-20之间 解题思路:将每一行连接到超级源点,容量为该行的 ...

  2. 【网络流#5】UVA 11082 最大流

    网络流题目最有意思的地方就是构图了,毕竟套模板每个人都会的 现在有一个矩阵,已知前i行元素之和a[i](1<=i<=n),前j列元素之和b[j](1<=j<=m),求一个可行的 ...

  3. uva Matrix Decompressing (行列模型)

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

  4. UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)

    题意: 知道矩阵的前i行之和,和前j列之和(任意i和j都可以).求这个矩阵.每个格子中的元素必须在1~20之间.矩阵大小上限20*20. 思路: 这么也想不到用网络流解决,这个模型很不错.假设这个矩阵 ...

  5. UVa 11082 - Matrix Decompressing(最大流)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  6. 紫书 例题11-8 UVa 11082(网络流最大流)

    这道题的建模真的非常的秀, 非常牛逼. 先讲建模过程.源点到每一行连一条弧, 容量为这一行的和减去列数, 然后每一列到汇点连一条弧, 容量为这一列 的和减去行数, 然后每一行和列之间连一条弧, 容量为 ...

  7. UVA - 11082 Matrix Decompressing (最大流,技巧)

    很经典的网络流模型,行编号和列编号分别看成一个点,行和列和分别看出容量,一个点(x,y)看出是一条边,边的容量下界是1,所以先减去1,之后在加上就好了. 建图的时候注意分配好编号,解从残留网络中的边找 ...

  8. [网络流最大流经典][uva 11082][矩阵解压]

    题目大意 分析 #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring ...

  9. UVa 11082 Matrix Decompressing(最大流)

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

随机推荐

  1. codevs 1488GangGang的烦恼

    题目链接:http://codevs.cn/problem/1488/ 写个高精度大数运算就行 #include<cstdio> #include<iostream> #inc ...

  2. 浅谈 switch和if

    1.所有的switch 都可以用if 替换,但所有的if不一定能被switch替换 2.:switch case直接跳到对应的case值里面执行相应代码.而if语句会执行一条一条判断语句,直到匹配到对 ...

  3. 【C#】Json数据 排版算法

    我从服务器上取得一串Json数据,然后想表示到画面上.不过服务器上取下的Json数据肯定是经过压缩的,空格和换行都没有.如果直接看,可读性非常差. 由于我这个软件是内部管理用的,使用者既能直接看懂Js ...

  4. AngularJS讲义-控制器

    在Angular中,控制器(Controller)就是基于JavaScript的构造方法,主要用来构造模型并建立模型和视图之间的数据绑定.控制器里面定义了应用程序的逻辑和行为. 通过ng-contro ...

  5. MyEclipse 关闭鼠标悬停提示

    preference --> MyEclipse -->Files and Editors--> Common Editor Preference --> Hovers 把里面 ...

  6. Installing Hadoop on Mac OSX Yosemite Tutorial Part 1.

    Installing Hadoop on Mac OSX Yosemite Tutorial Part 1. September 23, 2014 Marek 68 Comments Install ...

  7. soapUI 使用Property

    DRY 原则是一个比较普适的东西,在使用soapUI测试的时候,为了make life easy,我们必须要使用Property来集中化一些设置. 比如说从dev->test->uat 的 ...

  8. zTree v3.5配置

    页面 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ZTree3.aspx ...

  9. PMP 第二章 项目生命周期与组织

    1 项目组织机构类型有哪些? 区别是什么? 职能型  矩阵型  项目性 2 什么是事业环境因素? 什么是组织过程资产? 如何区分事业环境因素和组织过程资产? 事业环境因素:事业环境因素指围绕项目或能影 ...

  10. list[C++]

    //双向链表 #include <iostream> using namespace std; #include <list> int main(int argc, const ...