[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 ...
随机推荐
- 解决float浮动带来的父元素高度没有的问题---清除浮动
float的特性 : 1:使元素block块级化: 2:破坏性造成的紧密排列特性. 基于以上的特性,使得我们通常把浮动用来布局,带来的问题是,容易出问题,重用性不行,ie6-的版本下很多问题,因为它是 ...
- Integer
import static java.lang.System.*; public class IntegerTestOne{ public static void main(String []args ...
- nginx 缓存机制
nginx 缓存机制 Nginx缓存的基本思路 利用请求的局部性原理,将请求过的内容在本地建立一个副本,下次访问时不再连接到后端服务器,直接响应本地内容 Nginx服务器启动后,会对本地磁盘上的缓 ...
- java 获取项目绝对路径
String classPath = Thread.currentThread().getContextClassLoader().getResource("").getPath( ...
- 【转】从 ArcGIS for Desktop 发布地图服务
原文链接:http://resources.arcgis.com/zh-CN/help/tutorials/01z300000007000000.htm 本教程的目的是将地图服务直接从 ArcGIS ...
- 6/14 Sprint2 看板和燃尽图
中间部分还需要改进 小组评分:(团队总分为80) 团队成员: 101丘娟同学:21 107杨晓霞同学:18 108周诗琦同学:22 124陈程同 ...
- Asp.net图片文件上传
对课本上的代码进行了一点的优化 1.获取文件的名称和文件的后缀名 引用了System.IO, 用Path.GetFileNamehe()取得文件名和Path.GetExtension获取文件的后缀 2 ...
- Construct Binary Tree from Preorder and Inorder Traversal [LeetCode]
Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- 转-浅谈HTTP中Get与Post的区别
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP ...
- React Native 文本输入
TextInput是一个允许用户输入文本的基础组件.它有一个名为onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用.另外还有一个名为onSubmitEditing的属性, ...

