FZU2143Board Game(最小费用流)
题目大意是说有一个B矩阵,现在A是一个空矩阵(每个元素都为0),每次操作可以将A矩阵相邻的两个元素同时+1,但是有个要求就是A矩阵的每个元素都不可以超过K,求
这个的最小值
解题思路是这样的,新建起点与奇点(i != j)连K条边,第i条边的权值为(i - B)^2 - (i - 1 - B)^2 = 2 * i - 1 - 2 * B(这样可以保证如果此边的流量为a, 花费始终是(a-b)^2);另外新建终点与偶点相连,代价与上诉一致;
然后跑一遍最小费用流,知道cost>=0时为止。祥见代码:
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf (-((LL)1<<40))
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
#define rep(i, a, b) for(int i = a; i <= b; i ++) template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-; const int dx[] = {, , , -};
const int dy[] = {, , -, };
int T, N, M, K, B, ans = ; /*******************************************************************/
struct Edge {
int to, cap, flow, cost, next;
Edge(){}
Edge(int _n, int _v, int _c, int _f, int _cost){
next = _n; to = _v; cap = _c;
flow = _f; cost = _cost;
}
}; struct MCMF
{
int n, m, src, des;
int head[MAXN], tot;
Edge edges[MAXM];
int inq[MAXN];
int d[MAXN];
int p[MAXN];
int a[MAXN]; void init(int n) {
this->tot = ;
this->n = n;
mem1(head);
} void add_edge(int from, int to, int cap, int cost) {
edges[tot] = Edge(head[from], to, cap, , cost);
head[from] = tot ++;
edges[tot] = Edge(head[to], from, , , -cost);
head[to] = tot ++;
} bool bellman_ford(int s, int t, int& flow) {
for(int i = ; i < n; i ++) {
d[i] = INF;
inq[i] = ;
}
d[s] = ; inq[s] = ;
p[s] = ; a[s] = INF; queue<int>Q;
Q.push(s);
while(!Q.empty()) {
int u = Q.front(); Q.pop();
inq[u] = false;
for(int i = head[u]; i != -; i = edges[i].next) {
int v = edges[i].to;
if(edges[i].cap > edges[i].flow && d[v] > d[u] + edges[i].cost) {
d[v] = d[u] + edges[i].cost;
p[v] = i;
a[v] = min(a[u], edges[i].cap - edges[i].flow);
if(!inq[v]) {
Q.push(v);
inq[v] = ;
}
}
}
}
if(d[t] >= ) return false; flow += a[t];
ans += d[t] * a[t]; int u = t;
while(u != s) {
edges[p[u]].flow += a[t];
edges[p[u]^].flow -= a[t];
u = edges[p[u]^].to;
}
return true;
} int min_cost(int s, int t) {
int flow = ;
while(bellman_ford(s, t, flow));
return ans;
} };
/***************************************************************/ int idx(int i, int j) {
return (i - ) * M + j;
} int ok(int i, int j) {
return (i >= && i <= N && j >= && j <= M);
} MCMF mcmf; int main()
{
//FIN;
cin >> T;
rep (t, , T) {
scanf("%d %d %d", &N, &M, &K);
mcmf.init(N * M + );
mcmf.src = ; mcmf.des = N * M + ; ans = ;
rep (i, , N) rep (j, , M) {
scanf("%d", &B);
ans += B * B;
if(i % == j % ) rep (k, , K) {
mcmf.add_edge(mcmf.src, idx(i, j), , * k - - * B);
rep (k, , ) if(ok(i + dx[k], j + dy[k])) {
mcmf.add_edge(idx(i, j), idx(i + dx[k], j + dy[k]), INF, );
}
}
else rep (k, , K) {
mcmf.add_edge(idx(i, j), mcmf.des, , * k - - * B);
}
}
printf("Case %d: %d\n", t, mcmf.min_cost(mcmf.src, mcmf.des));
}
return ;
}
FZU2143Board Game(最小费用流)的更多相关文章
- POJ2195 最小费用流
题目:http://poj.org/problem?id=2195 处理出每个人到每个门的曼哈顿距离,分别建立容量为1费用为曼哈顿距离的边,在源点和每个人人之间建立容量为1费用为0的边,在门和汇点之间 ...
- HDU 4067 hdoj 4067 Random Maze 最小费用流
给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...
- POJ 2516:Minimum Cost(最小费用流)
https://vjudge.net/problem/11079/origin 题意:有N个商店和M个供应商和K种物品,每个商店每种物品有一个需求数,每个供应商每种物品有一个供应量,供应商到商店之间的 ...
- POJ-2175 Evacuation Plan 最小费用流、负环判定
题意:给定一个最小费用流的模型,根据给定的数据判定是否为最优解,如果不为最优解则给出一个比给定更优的解即可.不需要得出最优解. 解法:由给定的数据能够得出一个残图,且这个图满足了最大流的性质,判定一个 ...
- Going Home (hdu 1533 最小费用流)
集训的图论都快结束了,我才看懂了最小费用流,惭愧啊. = = 但是今天机械键盘到了,有弄好了自行车,好高兴\(^o^)/~ 其实也不是看懂,就会套个模板而已.... 这题最重要的就是一个: 多组输入一 ...
- POJ 2195 Going Home 最小费用流 裸题
给出一个n*m的图,其中m是人,H是房子,.是空地,满足人的个数等于房子数. 现在让每个人都选择一个房子住,每个人只能住一间,每一间只能住一个人. 每个人可以向4个方向移动,每移动一步需要1$,问所有 ...
- [haoi2010]订货 最小费用流
这道题oj上的标签是动态规划,但我想不出来动态规划怎么搞,空间不爆,时间也要爆的: 好的,不扯淡,此题正常做法是最小费用流: 这道题我写了两遍,为什么呢?原因是第一次写的时候,不会写费用流,又恰好没带 ...
- POJ 2516 Minimum Cost 最小费用流
题目: 给出n*kk的矩阵,格子a[i][k]表示第i个客户需要第k种货物a[i][k]单位. 给出m*kk的矩阵,格子b[j][k]表示第j个供应商可以提供第k种货物b[j][k]单位. 再给出k个 ...
- UVa 1658 (拆点法 最小费用流) Admiral
题意: 给出一个有向带权图,求从起点到终点的两条不相交路径使得权值和最小. 分析: 第一次听到“拆点法”这个名词. 把除起点和终点以外的点拆成两个点i和i',然后在这两点之间连一条容量为1,费用为0的 ...
随机推荐
- 51nod1394 差和问题
我只会用线段树写...不喜欢树状数组..其实跑的也不算慢?然后各种*的时候忘了longlong一直WA...药丸! 而且我不怎么会用map离散化...那么就sort+unique #include&l ...
- You must SET PASSWORD before executing this statement解决
[转载] MySql5.6操作时报错:You must SET PASSWORD before executing this statement解决 转载: http://blog.csdn.net/ ...
- 堆Heap
#pragma once#include <vector> // 小堆template<class T> //仿函数struct Less{ bool opera ...
- CentOS 6安装mock
最近工作中需要用到mock,这里介绍两种安装方式.本文的环境为CentOS 6.4 x86_64. 一,使用yum安装mock 安装第三方yum源RPMForge Centos5 64位 wget h ...
- js获取当前url信息
window.location 属性 描述 hash 设置或获取 href 属性中在井号"#"后面的分段. host 设置或获取 location 或 URL 的 hostname ...
- ORACLE 临时表空间清理
Oracle临时表空间主要用来做查询和存放一些缓冲区数据.临时表空间消耗的主要原因是需要对查询的中间结果进行排序.临时表空间的主要作用: 索引create或rebuildOrder by 或 grou ...
- 用xsd验证xml
using System; using System.Text; using System.Xml; namespace WebApplication1 { public partial class ...
- C# ComboBox自动完成功能的示例
先看一下关键代码: DataTable dt = new DataTable(); dt.Columns.Add("Name"); dt.Columns.Add("VV& ...
- web-ylbtech-数据库备份-数据库设计
ylbtech-DatabaseDesgin:web-ylbtech-数据库备份-数据库设计 DatabaseName:ylbtech Model:备份 Type:数据库备份设计 Url: 1.A,数 ...
- [转]Linux的chattr与lsattr命令详解
转自:http://www.cnblogs.com/yangxia-test/archive/2013/05/24/3096410.html 这两个命令是用来查看和改变文件.目录属性的,与chmod这 ...