[hdu 4307]Matrix
真是一道很好的题目喵~
一看题面真是无语了……很直接、很暴力、很恶心。说实话,除了 straight forward 我脑子里就没想过别的
上网看了一下居然是最小割,脑子里面一下子就清醒了,N<=1000 而且 A[i]=0 or 1 的,似乎数据上具备了网络流的前提~
现在来看一看那个公式:
稍微变一变:
这样就非常明显了,要最大化 D 的值,就要最小化后面括号里的表达式
而表达式的值仅和 ai 的值有关,可以视为:
若取 ai=0 时,要付出 ∑bij 的代价,若取 ai=1,则要付出 ci 的代价,同时,若 ai=1 且 aj=0 ,则又要付出 bij 的代价,问最小代价
这尼玛经典的最小割,建立源点 S 汇点 T ,令 ai 向 S 和 T 连边,若 ai 最终与 S 相连则 ai=1,否则 ai=0,再在 ai 和 aj 间连一条边,表示若 ai 和 aj 最后分属不同集合,则需付出 bij 的代价
然后,这道题就被 AC 了……
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define min(x, y) ((x)<(y) ? (x):(y))
const int inf=0x7FFFFFFF;
const int sizeOfPoint=;
const int sizeOfEdge=; int cases;
int N;
int S, T;
int B[sizeOfPoint][sizeOfPoint], Bi[sizeOfPoint], C[sizeOfPoint];
int h[sizeOfPoint];
inline int getint();
inline void putint(int); struct edge {int point, flow; edge * next, * pair;};
edge memory[sizeOfEdge], * port=memory;
edge * e[sizeOfPoint];
inline void clear() {port=memory; memset(e, , sizeof e);}
inline edge * newedge(int point, int flow, edge * next)
{
edge * ret=port++;
ret->point=point; ret->flow=flow; ret->next=next;
return ret;
}
inline void link(int u, int v, int f)
{
e[u]=newedge(v, f, e[u]); e[v]=newedge(u, , e[v]);
e[u]->pair=e[v]; e[v]->pair=e[u];
}
inline bool bfs();
inline int aug();
inline int dinic(); int main()
{
int ans; for (cases=getint();cases;cases--)
{
clear();
N=getint();
memset(Bi, , sizeof Bi);
for (int i=;i<=N;i++)
for (int j=;j<=N;j++)
Bi[i]+=(B[i][j]=getint());
for (int i=;i<=N;i++)
C[i]=getint();
ans=;
for (int i=;i<=N;i++) ans+=Bi[i]; S=; T=N+;
for (int i=;i<=N;i++)
link(S, i, Bi[i]),
link(i, T, C[i]);
for (int i=;i<=N;i++)
for (int j=;j<=N;j++) if (i!=j)
link(i, j, B[i][j]);
ans-=dinic();
putint(ans);
} return ;
}
inline int getint()
{
register int num=;
register char ch;
do ch=getchar(); while (ch<'' || ch>'');
do num=num*+ch-'', ch=getchar(); while (ch>='' && ch<='');
return num;
}
inline void putint(int num)
{
char stack[];
register int top=;
if (num==) stack[top=]='';
for ( ;num;num/=) stack[++top]=num%+'';
for ( ;top;top--) putchar(stack[top]);
putchar('\n');
}
inline bool bfs()
{
static int q[sizeOfPoint];
int l=, r=;
memset(h, 0xFF, sizeof h); h[T]=;
for (q[r++]=T;l<r;l++)
{
int u=q[l];
for (edge * i=e[u];i;i=i->next) if (i->pair->flow && h[i->point]==-)
h[q[r++]=i->point]=h[u]+;
}
return h[S]>=;
}
inline int aug()
{
static edge * t[sizeOfPoint], * path[sizeOfPoint];
static int aug[sizeOfPoint];
int flow=;
memset(aug, , sizeof aug); aug[S]=inf;
memset(path, , sizeof path);
memmove(t, e, sizeof e);
for (int u=S; ; )
{
if (u==T)
{
flow+=aug[T];
for (edge * i=path[T];i;i=path[i->point])
i->pair->flow-=aug[T], i->flow+=aug[T], aug[i->point]-=aug[T];
for (edge * i=path[T];i && u==T;i=path[i->point]) if (aug[i->point])
u=i->point;
}
edge *& i=t[u];
for ( ;i && (!i->flow || h[i->point]+!=h[u]);i=i->next);
if (i)
{
path[i->point]=i->pair; aug[i->point]=min(aug[u], i->flow);
u=i->point;
}
else
{
if (u==S) break;
h[u]=-;
u=path[u]->point;
}
}
return flow;
}
inline int dinic()
{
register int flow=;
for ( ;bfs();flow+=aug());
return flow;
}
本傻装B系列
这道题告诉我们,如果要求的是一个最大/小化某个表达式的数组,且每个数字的取值范围都很小时可以考虑用最小割做~
[hdu 4307]Matrix的更多相关文章
- HDU 4920 Matrix multiplication(bitset)
HDU 4920 Matrix multiplication 题目链接 题意:给定两个矩阵,求这两个矩阵相乘mod 3 思路:没什么好的想法,就把0的位置不考虑.结果就过了.然后看了官方题解,上面是用 ...
- HDU 2686 Matrix 3376 Matrix Again(费用流)
HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,仅仅是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 ...
- hdu 2686 Matrix 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...
- hdu 5569 matrix dp
matrix Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5569 D ...
- hdu 2119 Matrix(二分匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2119 Matrix Time Limit: 5000/1000 MS (Java/Others) ...
- HDU 5671 Matrix 水题
Matrix 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5671 Description There is a matrix M that has ...
- HDU - 233 Matrix
原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5015 解题思路:一看到题目,感觉是杨辉三角形,然后用组合数学做,不过没想出来怎么做,后来看数据+递推思 ...
- HDU——2119 Matrix
Matrix Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 2830 Matrix Swapping II (预处理的线性dp)
Matrix Swapping II Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
随机推荐
- HTML中IFrame父窗口与子窗口相互操作
一.Iframe篇 //&&&&&&&&&&&&&&&&&&am ...
- mac pycharm配置 python
一.首先查看自己安装的python的路径 在terminal运行 which python(which命令只是根据PATH环境变量找) 例如:/usr/bin/python 二.设置python版本 ...
- datatables设置解析
条信息" "sSearch":"搜索" 基本的命令 aaSorting:参数是个数组 [[],[]]单独定义每一列的排序方式 aaSortingFi ...
- 项目打包文件build.xml
Make命令其实就是一个项目管理工具,而Ant所实现功能与此类似.像make,gnumake和nmake这些编译工具都有一定的缺陷,但是Ant却克服了这些工具的缺陷.最初Ant开发者在开发跨平台的应用 ...
- CENTOS修改主机名
1.临时修改主机名 显示主机名: zhouhh@zzhh64:~$ hostname zhh64 修改主机名: zhouhh@zzhh64:~$ sudo hostname zzofs zhouhh@ ...
- winform app.config文件的动态配置
获取 获取应用程序exe.config文件中 节点value值 /// <summary> /// 功能: 读取应用程序exe.config文件中 /// appSettings节点下 ...
- WPF:带复选框CheckBox的树TreeView
最近要用WPF写一个树,同事给了我一个Demo(不知道是从哪里找来的),我基本上就是参照了这个Demo. 先放一下效果图(3棵树): 这个树索要满足的条件是: 父节点.Checked=true时,子节 ...
- java length属性 length()方法 size()方法
length是属性,一般用来说明数组的长度 length()是方法,针对字符串String说的,用来求数组中某个元素的字符串长度 String str={"adfasf",&quo ...
- svn用法:摘自http://wh-vip-126-com200907043220.iteye.com/blog/424642
下载最新版本svn(http://www.visualsvn.com/server/ ) 1.安装SVN 2.创建user与repository 3.Eclipse下配置SVN插件 3.1帮助- ...
- IE6 一些兼容性问题及处理方法
1.IE6怪异解析之padding与border算入宽高 原因:未加文档声明造成非盒模型解析 解决方法:加入文档声明<!doctype html> 2.IE6在块元素.左右浮动.设定mar ...

