[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 ...
随机推荐
- requestAnimationFrame 动画
requestAnimationFrame : 调用这个方法,就是告诉浏览器要执行动画了,从而浏览器自动计算动画时间间隔,从而在恰当的时候刷新UI, 动画更加平滑. 他的用法和setTimeout() ...
- 理解RxJava线程模型
RxJava作为目前一款超火的框架,它便捷的线程切换一直被人们津津乐道,本文从源码的角度,来对RxJava的线程模型做一次深入理解.(注:本文的多处代码都并非原本的RxJava的源码,而是用来说明逻辑 ...
- 在eclipse中导入weka(小白在路上)
第一步:新建一个java工程,new->javaproject,假设工程名为wekatest 第二步:导入weka.jar 第三步:src关联 导入后有许多的.class文件,直接双击打开是看不 ...
- 关于如何来构造一个String类
今天帮着一位大二的学弟写了一个String的类,后来一想这个技术点,也许不是什么难点,但是还是简单的记录一些吧! 为那些还在路上爬行的行者,剖析一些基本的实现..... 内容写的过于简单,没有涉及到其 ...
- 51nod 1459 迷宫游戏(dij)
题目链接:51nod 1459 迷宫游戏 dij裸题. #include<cstdio> #include<cstring> #include<algorithm> ...
- 读javascript高级程序设计13-JSON
JSON是一个轻量级的数据格式,可以简化表示数据结构的工作量.在实际工作中,我们经常用它来传递数据,不过对于其使用的一些细节还是需要注意的.在ECMAScript5中定义了原生的JSON对象,可以用来 ...
- MVC模式与三层架构的区别
之前总是混淆MVC表现模式和三层架构模式,为此记录下. 三层架构和MVC是有明显区别的,MVC应该是展现模式(三个加起来以后才是三层架构中的UI层) 三层架构(3-tier application) ...
- Masonry使用注意篇
简要 自动布局最重要的是约束:UI元素间关系的数学表达式.约束包括尺寸.由优先级和阈值管理的相对位置.它们是添加剂,可能导致约束冲突 .约束不足造成布局无法确定 .这两种情况都会产生异常. 使用前:A ...
- IE下只读INPUT键入BACKSPACE 后退问题(readonly='true')
在IE下,如果在readonly的input里面键入backspace键,会触发history.back(), 用以下jquery代码修正之 $("input[readOnly]" ...
- 【matlab】MATLAB程序调试方法和过程
3.8 MATLAB程序的调试和优化 在MATLAB的程序调试过程中,不仅要求程序能够满足设计者的设计需求,而且还要求程序调试能够优化程序的性能,这样使得程序调试有时比程序设计更为复杂.MATLAB ...

