[TJOI2014] [Bzoj3996] 线性代数 [网络流,最小割]
由原式,可以推出D=Σ(i=1,n,Σ(j=1,n,A[i]*A[j]*B[i][j]))-Σ(i=1,n,A[i]*C[i])
$D=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}A[i]*A[j]*B[i][j]-\sum\limits_{i=1}^{n}A[i]*C[i]$
,故建图方法如下:由源点像第一层n*n个点连边,边权为$B[i][j]$,由第一层像第二层连边,边权正无穷,由第二层向汇点连边,边权$C[i]$。最终答案为$\sum B-MAXFLOW$。
推导过程:
(A * B - C) * AT
(1*n) (n*n) (1*n) (n*1)
=A*B * AT - C * AT
(1*n) (n*1) (1*1)
令$P[i][j]=\sum\limits_{k=1}^{n}A[i][k]*B[k][j]$
$A^T[i][j]=A[j][i]=A[i](j=1)$
原式=$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}A[i]*B[i][j]*A[j]-\sum\limits_{i=1}^{n}A[i]*C[i]$
参考HZWER博客:http://hzwer.com/6814.html
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <queue> using namespace std; template<const int _n>
struct Edge
{
struct Edge_base { int to,next,w; }e[_n];
int p[_n],cnt;
Edge() { clear(); }
int start(const int x) { return p[x]; }
void insert(const int x,const int y,const int z)
{ e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; p[x]=cnt; return ; }
void clear() { cnt=,memset(p,,sizeof(p)); }
Edge_base& operator[](const int x) { return e[x]; }
}; int SSS,TTT,cur[];
int n,tot,level[];
Edge<> e; bool Bfs(const int S)
{
int i,t;
queue<int> Q;
memset(level,,sizeof(int)*(n+n*n+));
level[S]=;
Q.push(S);
while(!Q.empty())
{
t=Q.front();Q.pop();
for(i=e.start(t);i;i=e[i].next)
{
if(!level[e[i].to] && e[i].w)
{
level[e[i].to]=level[t]+;
Q.push(e[i].to);
}
}
}
return level[TTT];
} int Dfs(const int S,const int bk)
{
if(S==TTT)return bk;
int rest=bk;
for(int &i=cur[S];i;i=e[i].next)
{
if(level[e[i].to]==level[S]+ && e[i].w)
{
int flow=Dfs(e[i].to,min(rest,e[i].w));
e[i].w-=flow;
e[i^].w+=flow;
if((rest-=flow)<=)break;
}
}
if(bk==rest)level[S]=;
return bk-rest;
} int Dinic()
{
int flow=;
while(Bfs(SSS))
{
memcpy(cur,e.p,sizeof(int)*(n+n*n+));
flow+=Dfs(SSS,0x3f3f3f3f);
}
return flow;
} int getint()
{
int data=;
char ch=getchar();
while(ch<'' || ch>'')ch=getchar();
while(ch>='' && ch<='')data=data*+ch-,ch=getchar();
return data;
} int main()
{
int i,j,x,Sum=; n=getint();
tot=n;SSS=tot+n*n+;TTT=SSS+;
for(i=;i<=n;++i)
{
for(j=;j<=n;++j)
{
x=getint();++tot;
e.insert(SSS,tot,x);
e.insert(tot,SSS,);
e.insert(tot,i,0x3f3f3f3f);
e.insert(i,tot,);
e.insert(tot,j,0x3f3f3f3f);
e.insert(j,tot,);
Sum+=x;
}
} for(i=;i<=n;++i)
{
x=getint();
e.insert(i,TTT,x);
e.insert(TTT,i,);
} printf("%d\n",Sum-Dinic()); return ;
}
[TJOI2014] [Bzoj3996] 线性代数 [网络流,最小割]的更多相关文章
- 【BZOJ3996】[TJOI2015]线性代数(最小割)
[BZOJ3996][TJOI2015]线性代数(最小割) 题面 BZOJ 洛谷 题解 首先把式子拆开,发现我们的答案式就是这个: \[\sum_{i=1}^n\sum_{j=1}^n B_{i,j} ...
- 【题解】 bzoj3894: 文理分科 (网络流/最小割)
bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...
- 【bzoj3774】最优选择 网络流最小割
题目描述 小N手上有一个N*M的方格图,控制某一个点要付出Aij的代价,然后某个点如果被控制了,或者他周围的所有点(上下左右)都被控制了,那么他就算是被选择了的.一个点如果被选择了,那么可以得到Bij ...
- 【bzoj1143】[CTSC2008]祭祀river Floyd+网络流最小割
题目描述 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成的网络.每条河 ...
- 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan
题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...
- 【bzoj1976】[BeiJing2010组队]能量魔方 Cube 网络流最小割
题目描述 一个n*n*n的立方体,每个位置为0或1.有些位置已经确定,还有一些需要待填入.问最后可以得到的 相邻且填入的数不同的点对 的数目最大. 输入 第一行包含一个数N,表示魔方的大小. 接下来 ...
- 【bzoj4177】Mike的农场 网络流最小割
题目描述 Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中第i个牲畜围栏中的动物长大后,每只牛可以卖a[i] ...
- 【bzoj3438】小M的作物 网络流最小割
原文地址:http://www.cnblogs.com/GXZlegend/p/6801522.html 题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物 ...
- 【bzoj3144】[Hnoi2013]切糕 网络流最小割
题目描述 输入 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤ ...
随机推荐
- Linux特殊符号及基础正则表达式
第1章 特殊符号 1.1 引号系列 1.1.1 单引号 所见即所得 单引号里面的内容会原封不动的输出 [root@oldboyedu50-lnb ~]# echo 'oldboy $LANG $PS ...
- Sara Cope关于text-shadow的介绍
作者:Sara Cope p { text-shadow: 1px 1px 1px #000; } 你可以通过逗号“,”应用多个文本阴影. p { text-shadow: 1px 1px 1px # ...
- Coursera公开课-Machine_learing:编程作业2
第三周编程作业:Logistic Regression 代码包在gitlab上:https://gitlab.com/luntai/Machine_Learning
- C语言关键字之sizeof
C语言关键字 sizeof 是一个操作符,返回对象或类型所占内存字节数,类型为size_t(定义在<stddef.h>),有2种用法: sizeof unary-expression si ...
- JS高级——apply与call
上下文调用模式 可以修改this的值,也就是可以修改函数的调用方式,apply.call可以修改函数调用上下文,也就是this的值 <script> var name = "莱昂 ...
- 移动web——touch事件介绍
基本概念 1.在移动web端点击事件或者滑动屏幕.捏合等动作都是由touchstar.touchmove.touchend这三个事件组合在一起使用的 2.click事件在移动端会有0.2秒的延迟,下面 ...
- JS——鼠标在盒子中的坐标
核心思想: 1.复杂版本:鼠标pageX.pageY的值减去盒子距离顶端的offsetLeft.offsetTop值就是鼠标在盒子中的坐标 2.简单版本:offsetX.offsetY就可获取鼠标相对 ...
- 控制台——EventLog实现事件日志操作
我们应该如何通过写代码的方式向其中添加“日志”呢? 在操作之前,先明确几个概念: 1:事件日志名(logName):“事件查看器”中的每一项,如“应用程序”.“Internet Explorer”.“ ...
- python函数参数的区别
在运用python的过程中,发现当函数参数为list的时候,在函数内部调用list.append()会改变形参,与C/C++的不太一样,查阅相关资料,在这里记录一下. python中id可以获取对象的 ...
- redis在linux下安装以及扩展
安装过redis后发现回头忘了,今天重新安装记录下 首先 我是在home下创建redis文件 mkdir redis 然后直接用wget安装 wget http://download.redis ...