题意

给出一个\(N \times N\)的矩阵\(B\)和一个\(1 \times N\)的矩阵\(C\)。求出一个\(1 \times N\)的01矩阵\(A\),使得$$ D = ( A * B - C ) * A^T $$最大,其中\(A ^ T\)是矩阵\(A\)的转置。(\(n<=500\))

分析

好神的题。首先我们容易推出一个式子:

\[D = \sum_{i=1}^{n} \sum_{j=1}^{n} a_i \times a_j \times b_{i, j} - \sum_{i=1}^{n} a_i \times c_i
\]

题解

选\(b_{i, j}\)则必须选\(a_i\)、\(a_j\),而选\(a_i\)就必须选\(c_i\)。

那么可以看成:

\(a_i\)为一个点,权值为\(-c_i\),表示选了\(a_i\)就必须选\(c_i\)

\(b_{i, j}\)为一个点,权值为\(b_{i, j}\),向\(a_i、a_j\)连有向边,表示选了\(b_{i, j}\)就必须选\(a_i、a_j\)。

于是问题变成求最大权闭合子图....

由于某种原因,这个网络流跑的飞起?似乎成了二分图复杂度变成\(O(mn^{0.5})\)了?感觉不科学啊QAQ

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. inline int getint() {
  4. int x=0, c=getchar();
  5. for(; c<48||c>57; c=getchar());
  6. for(; c>47&&c<58; x=x*10+c-48, c=getchar());
  7. return x;
  8. }
  9. const int N=605, vN=N*N+N, oo=~0u>>1;
  10. int ihead[vN], cnt=1;
  11. struct E {
  12. int next, to, cap;
  13. }e[6*N*N+2*N];
  14. inline void add(int x, int y, int cap) {
  15. e[++cnt]=(E){ihead[x], y, cap}; ihead[x]=cnt;
  16. e[++cnt]=(E){ihead[y], x, cap}; ihead[y]=cnt;
  17. }
  18. inline int min(const int &a, const int &b) {
  19. return a<b?a:b;
  20. }
  21. int isap(int s, int t, int n) {
  22. static int gap[vN], cur[vN], d[vN], p[vN];
  23. gap[0]=n;
  24. int r=0, x=s, i, f;
  25. for(; d[s]<n;) {
  26. for(i=cur[x]; i && !(e[i].cap && d[x]==d[e[i].to]+1); i=e[i].next);
  27. if(i) {
  28. p[e[i].to]=cur[x]=i;
  29. if((x=e[i].to)==t) {
  30. for(f=oo, x=t; x!=s; f=min(f, e[p[x]].cap), x=e[p[x]^1].to);
  31. for(r+=f, x=t; x!=s; e[p[x]].cap-=f, e[p[x]^1].cap+=f, x=e[p[x]^1].to);
  32. }
  33. }
  34. else {
  35. if(!--gap[d[x]]) break;
  36. d[x]=n;
  37. for(i=ihead[x]; i; i=e[i].next) {
  38. if(e[i].cap && d[x]>d[e[i].to]+1) {
  39. d[x]=d[e[i].to]+1;
  40. cur[x]=i;
  41. }
  42. }
  43. ++gap[d[x]];
  44. if(x!=s) x=e[p[x]^1].to;
  45. }
  46. }
  47. return r;
  48. }
  49. int main() {
  50. int n=getint(), sum=0, S, T;
  51. S=n*(n+1)+1, T=S+1;
  52. for(int i=1; i<=n; ++i) {
  53. for(int j=1; j<=n; ++j) {
  54. int id=i*n+j, w=getint();
  55. add(id, T, w);
  56. if(i!=j) add(i, id, oo);
  57. add(j, id, oo);
  58. sum+=w;
  59. }
  60. }
  61. for(int i=1; i<=n; ++i) {
  62. add(S, i, getint());
  63. }
  64. printf("%d\n", sum-isap(S, T, T));
  65. return 0;
  66. }

【BZOJ】3996: [TJOI2015]线性代数的更多相关文章

  1. bzoj 3996: [TJOI2015]线性代数 [最小割]

    3996: [TJOI2015]线性代数 题意:给出一个NN的矩阵B和一个1N的矩阵C.求出一个1*N的01矩阵A.使得 \(D=(A * B-C)* A^T\)最大.其中A^T为A的转置.输出D.每 ...

  2. ●BZOJ 3996 [TJOI2015]线性代数

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3996 题解: 好题啊.(不太熟悉矩阵相关,所以按某些博主的模型转换来理解的)首先,那个式子可 ...

  3. bzoj 3996 [TJOI2015]线性代数——最小割

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3996 b[ i ][ j ] 要计入贡献,当且仅当 a[ i ] = 1 , a[ j ] ...

  4. bzoj 3996: [TJOI2015]线性代数

    Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大.其中A^T为A的转置.输出D Input 第一行输入一个整数N,接 ...

  5. bzoj 3996: [TJOI2015]线性代数【最小割】

    把转置矩阵看成逆矩阵吓傻了233 首先按照矩乘推一下式子: \[ D=\sum_{i=1}^n a[i]*(\sum_{j=1}^n a[j]*b[j][i])-c[i] \] \[ D=(\sum_ ...

  6. 【BZOJ 3996】 3996: [TJOI2015]线性代数 (最小割)

    3996: [TJOI2015]线性代数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1368  Solved: 832 Description 给 ...

  7. 【BZOJ3996】[TJOI2015]线性代数(最小割)

    [BZOJ3996][TJOI2015]线性代数(最小割) 题面 BZOJ 洛谷 题解 首先把式子拆开,发现我们的答案式就是这个: \[\sum_{i=1}^n\sum_{j=1}^n B_{i,j} ...

  8. BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图

    BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图 Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大. ...

  9. 【LG3973】[TJOI2015]线性代数

    [LG3973][TJOI2015]线性代数 题面 洛谷 题解 正常解法 一大堆矩阵乘在一起很丑对吧 化一下柿子: \[ D=(A*B-C)*A^T\\ \Leftrightarrow D=\sum_ ...

随机推荐

  1. PHP代码获取客户端IP地址经纬度及所在城市

    echo $_SERVER['HTTP_HOST'];//echo $_SERVER['REQUEST_URI'];$getIp=$_SERVER["REMOTE_ADDR"];e ...

  2. eclipse中ctrl+h默认打开是JavaSearch,怎么设置成默认打开是FileSearch

    window->preferences->General->keys. 找到File Search(有搜索框的,可以搜索),然后在下方 Binding按下ctrl +h .

  3. python拆分CANLog

    通过CANOE 导出的log通常有很多个ID的数据,如何才能找到某一个ID下的特殊的信号?利用python可以简单的进行这个步骤,代码如下: 说明: 最终的效果是将log信息,分不同的ID进行拆分,并 ...

  4. xpath定位中starts-with、contains和text()的用法

    starts-with 顾名思义,匹配一个属性开始位置的关键字 contains 匹配一个属性值中包含的字符串 text() 匹配的是显示文本信息,此处也可以用来做定位用 eg //input[sta ...

  5. Unity3D 接完GVR SDk后如何插入自己的java代码

    1.用Eclipse创建一个Android Application Project 2.用压缩软件打开gvr_android_common.aar和unitygvractivity.aar,分别把里面 ...

  6. Windows Server 2012 在桌面上显示”我的电脑”图标

    1.本地方式如果是在Windows Server 2012本地控制台下,直接按Win(键盘上的微软徽标键)+R,输入: rundll32.exe shell32.dll,Control_RunDLL ...

  7. ABAP 将单元格设置编辑状态 FORM

    FORM set_style  USING   fieldname                         style TYPE string                 CHANGING ...

  8. [转]加速Android Studio/Gradle构建

    加速Android Studio/Gradle构建 android android studio gradle   已经使用Android Studio进行开发超过一年,随着项目的增大,依赖库的增多, ...

  9. oracle中trunc()和to_char()函数用法

    -----trunc(for date) select sysdate from dual; --当前时间  2016/9/7 10:32:04select trunc(sysdate) from d ...

  10. java内存溢出和内存泄露

    虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险. 最近在网上搜集了一些资料,现整理如下: —————————————————————————————————————— ...