[bzoj] 3996 [TJOI2015]线性代数
2015-06-04 19:35
309 查看
题目要求
ans=Maximize∑i=1NA1,i⋅⎛⎝∑j=1NA1,j⋅Bi,j−C1,i⎞⎠ans = Maximize\quad\sum_{i=1}^{N} A_{1,i}\cdot\left(\sum_{j=1}^{N}A_{1,j}\cdot B_{i,j}-C_{1,i}\right)
方法一
直接推到最小割
因为目标函数最大化,所以先将其转为最小化
令
sum=∑i=1N∑j=1NBi,jsum=\sum_{i=1}^{N}\sum_{j=1}^{N}B_{i,j}
cost=∑i=1NA1,i⋅⎛⎝∑j=1N(1−A1,j)⋅Bi,j+Ci⎞⎠+∑i=1N(1−A1,i)⋅∑j=1NBi,jcost =\sum_{i=1}^{N}A_{1,i}\cdot\left(\sum_{j=1}^{N}\left(1-A_{1,j}\right)\cdot B_{i,j}+C_{i}\right)+\sum_{i=1}^{N}\left(1-A_{1,i}\right)\cdot\sum_{j=1}^{N}B_{i,j}
则
ans=tot−Minimize(cost)ans = tot-Minimize\left(cost\right)
方法二
最大权闭合子图
一个Bi,jB_{i,j}被加入答案,那么A1,iA_{1,i}与A1,jA_{1,j}必须都是11,在图中可以看做点Bi,jB_{i,j}被选的前提是A1,iA_{1,i}与A1,jA_{1,j}被选
一个C1,iC_{1,i}被答案减去,A1,iA_{1,i}必须是11,在图中可以看做A1,iA_{1,i}的点权.
于是我们得到了一个有向图,图中的每个Bi,jB_{i,j}都由两个点A1,iA_{1,i}与A1,jA_{1,j}指向.
每个AA点的点权为 −C1,i-C_{1,i} , 每个BB点 的点权是Bi,jB_{i,j}
然后裸最大权闭合子图辣
ans=Maximize∑i=1NA1,i⋅⎛⎝∑j=1NA1,j⋅Bi,j−C1,i⎞⎠ans = Maximize\quad\sum_{i=1}^{N} A_{1,i}\cdot\left(\sum_{j=1}^{N}A_{1,j}\cdot B_{i,j}-C_{1,i}\right)
方法一
直接推到最小割
因为目标函数最大化,所以先将其转为最小化
令
sum=∑i=1N∑j=1NBi,jsum=\sum_{i=1}^{N}\sum_{j=1}^{N}B_{i,j}
cost=∑i=1NA1,i⋅⎛⎝∑j=1N(1−A1,j)⋅Bi,j+Ci⎞⎠+∑i=1N(1−A1,i)⋅∑j=1NBi,jcost =\sum_{i=1}^{N}A_{1,i}\cdot\left(\sum_{j=1}^{N}\left(1-A_{1,j}\right)\cdot B_{i,j}+C_{i}\right)+\sum_{i=1}^{N}\left(1-A_{1,i}\right)\cdot\sum_{j=1}^{N}B_{i,j}
则
ans=tot−Minimize(cost)ans = tot-Minimize\left(cost\right)
方法二
最大权闭合子图
一个Bi,jB_{i,j}被加入答案,那么A1,iA_{1,i}与A1,jA_{1,j}必须都是11,在图中可以看做点Bi,jB_{i,j}被选的前提是A1,iA_{1,i}与A1,jA_{1,j}被选
一个C1,iC_{1,i}被答案减去,A1,iA_{1,i}必须是11,在图中可以看做A1,iA_{1,i}的点权.
于是我们得到了一个有向图,图中的每个Bi,jB_{i,j}都由两个点A1,iA_{1,i}与A1,jA_{1,j}指向.
每个AA点的点权为 −C1,i-C_{1,i} , 每个BB点 的点权是Bi,jB_{i,j}
然后裸最大权闭合子图辣
[code]/****************************************\ * Author : ztx * Title : [bzoj] 3996 [TJOI2015]线性代数 * ALG : 嘛,最小割大水题,但是把它想成最大权闭合子图就太高达上了QAQ * CMT : * Time : \****************************************/ #include <cstdio> #define Rep(i,l,r) for(i=(l);i<=(r);i++) #define rep(i,l,r) for(i=(l);i< (r);i++) #define Rev(i,r,l) for(i=(r);i>=(l);i--) #define rev(i,r,l) for(i=(r);i> (l);i--) typedef long long ll ; int CH , NEG ; template <typename TP>inline void read(TP& ret) { ret = NEG = 0 ; while (CH=getchar() , CH<'!') ; if (CH == '-') NEG = true , CH = getchar() ; while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ; if (NEG) ret = -ret ; } template <typename TP>inline void readc(TP& ret) { while (ret=getchar() , ret<'!') ; while (CH=getchar() , CH>'!') ; } template <typename TP>inline void reads(TP *ret) { ret[0]=0;while (CH=getchar() , CH<'!') ; while (ret[++ret[0]]=CH,CH=getchar(),CH>'!') ; ret[ret[0]+1]=0; } #define maxN 300010LL #define maxM 900010LL #define infi 0x7f7f7f7fLL #define min(x,y) ((x)<(y)?(x):(y)) struct FST { int to,next,flow; } e[maxM<<1] ; int star[maxN] = {0} , tote = 1 ; inline void AddEdge(int u,int v,int cap) { e[++tote].to=v;e[tote].flow=cap;e[tote].next=star[u];star[u]=tote; e[++tote].to=u;e[tote].flow=0;e[tote].next=star[v];star[v]=tote; } int n , S , T , N ; int h[maxN] = {0} , vh[maxN] = {0} ; int dfs(int u,int flowu) { int p , tmp = h[u]+1 ; int flow = 0 , flowv ; if (u == T) return flowu ; for (p = star[u] ; p ; p = e[p].next) if (e[p].flow>0 && h[u]==h[e[p].to]+1) { flowv = dfs(e[p].to,min(e[p].flow,flowu-flow)) ; flow += flowv ; e[p].flow -= flowv , e[p^1].flow += flowv ; if (h[S]==N || flow==flowu) return flow ; } for (p=star[u] ; p ; p=e[p].next) if (e[p].flow>0 && h[e[p].to]<tmp) tmp = h[e[p].to] ; if (--vh[h[u]] == 0) h[S] = N ; else ++vh[h[u]=tmp+1] ; return flow ; } inline int SAP() { int ret = 0 ; vh[0] = N ; while (h[S] < N) ret += dfs(S,infi) ; return ret ; } inline int A(int i) { return n*n+i ; } inline int B(int i,int j) { return (i-1)*n+j ; } int main() { int i , j , w , ans ; #define READ #ifdef READ freopen("data.in" ,"r",stdin ) ; freopen("data.out","w",stdout) ; #endif read(n) ; S = n*n+n+1 , T = N = S+1 ; ans = 0 ; Rep (i,1,n) Rep (j,1,n) { read(w) ; ans += w ; AddEdge(B(i,j),T,w) ; AddEdge(A(i),B(i,j),infi) ; AddEdge(A(j),B(i,j),infi) ; } Rep (i,1,n) { read(w) ; AddEdge(S,A(i),w) ; } ans -= SAP() ; printf("%d\n", ans) ; #ifdef READ fclose(stdin) ; fclose(stdout) ; #else getchar() ; getchar() ; #endif return 0 ; }
相关文章推荐
- TC安装全系列教程
- JSF第一步
- Reverse Nodes in k-Group
- Java中继承thread类与实现Runnable接口的区别
- Oracle Linux: Error "Missing Or Invalid IPv4 Prefix '0' On Linux Server" (文档 ID 1522095.1)
- Jquery ready和window.onload方法区别
- likely(x)与unlikely(x)函数,即__builtin_expect的使用(转)
- 文章标题
- 几个有用的iOS开源代码
- BZOJ 3479: [Usaco2014 Mar]Watering the Fields( MST )
- (10.3.4)如何写出好的PRD
- 论文写不下去了怎么办?
- zoj 3229 上下界网络最大可行流带输出方案
- 团队工作总结及自评 & 补上来的用户调研
- 去除Ubuntu文件夹有锁标志
- java实现接口与继承类的区别
- unity 根据纪元时间(1970/1/1)转换为DateTime
- POJ 3687 逆序拓扑
- 浅谈UitextField值变化的实时监视
- 随笔2