• [BZOJ 3996] [TJOI 2015] 线性代数


    3996: [TJOI2015]线性代数

    Time Limit: 10 Sec
    Memory Limit: 128 MB

    Description

    给出一个N*N的矩阵B和一个1*N的矩阵C。求出一个1*N的01矩阵A.使得

    D=(A*B-C)*A^T最大。其中A^T为A的转置。输出D

    Input

    第一行输入一个整数N,接下来N行输入B矩阵,第i行第J个数字代表Bij.
    接下来一行输入N个整数,代表矩阵C。矩阵B和矩阵C中每个数字都是不超过1000的非负整数。
     

    Output

    输出最大的D

     

    Sample Input

    3
    1 2 1
    3 1 0
    1 2 3
    2 3 7

    Sample Output

    2

    HINT

     1<=N<=500

    【题解】

    花了好久时间化简,最后化简出来是

    我们发现,a是一个01矩阵,然后其实就可以化成这么一个问题:

    有n个东西,选了i,j两件东西能得到b[i,j]的价值,然而选i需要c[i]的花费,选j需要c[j]的花费……

    据大聚聚们说,这是一个经典的最小割模型。

    建立S,T。

    S连(i,j)边,边权为b[i,j],(i,j)连i、连j边,边权均为∞,i向T连边,边权为c[i]。

    然后求最小割,最后答案就是

    sum(b[i][j])-最小割答案  (i∈[1..n],j∈[1..n])

    最小割今天早上刚写过dinic哈哈=-=

    然而第一次写边链表,好在也AC了

    STL的queue被卡RE了(后来发现并没有) TAT好可怕要自己写队列了

    然后了一堆地方有bug调了一个小时

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<algorithm>
     6 #include<math.h>
     7 #include<string>
     8 using namespace std;
     9 const int inf=210000;
    10 int c[250510],head[250510];
    11 long long ans;
    12 int q[250510];
    13 int s,t,n,tt,heads,tail;
    14 struct edge {
    15     int next,num,x;
    16 }e[2505010];
    17 int read2() {
    18     int x=0; int f=1;
    19     char ch=getchar();
    20     while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
    21     while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    22     return x*f;
    23 }
    24 inline void f(int a,int b,int w) {
    25     e[++tt].next=head[a];head[a]=tt;
    26     e[tt].num=w;e[tt].x=b;
    27     e[++tt].next=head[b];head[b]=tt;
    28     e[tt].num=0;e[tt].x=a;
    29 }
    30 bool bfs() {
    31     for (int i=s;i<=t;++i) c[i]=0;
    32     heads=tail=1;
    33     q[tail]=s;c[s]=1;
    34     while(heads<=tail) {
    35         int top=q[heads++];
    36         for (int i=head[top];i;i=e[i].next) {
    37             int x=e[i].x,num=e[i].num;
    38             if(num==0||c[x]>0) continue;
    39             c[x]=c[top]+1;
    40             q[++tail]=x;
    41             if(x==t) return 1;
    42         }
    43     }
    44     return 0;
    45 }
    46 int dfs(int y,int low) {
    47     if(y==t) return low;
    48     int flow,r=low;
    49     for (int i=head[y];i;i=e[i].next) {
    50         int x=e[i].x,num=e[i].num;
    51         if(c[x]!=c[y]+1 || num==0) continue;
    52         flow=dfs(x,min(r,num));
    53         r-=flow;
    54         e[i].num-=flow; e[i^1].num+=flow;
    55         if(!r) return low;
    56     }
    57     if(r==low) c[y]=-1;
    58     return low-r;
    59 }
    60 int main() {
    61     //freopen("algebra.in","r",stdin);
    62     //freopen("algebra.out","w",stdout);
    63     int k,w;
    64     n=read2();s=0,t=n*n+n+1; k=n;
    65     for (int i=1;i<=n;++i)
    66         for (int j=1;j<=n;++j) {
    67             w=read2();
    68             ans+=w;
    69             f(s,++k,w);
    70             f(k,i,inf);
    71             f(k,j,inf);
    72         }
    73     for (int i=1;i<=n;++i) {
    74         w=read2();
    75         f(i,t,w);
    76     }
    77     while(bfs()) ans-=dfs(s,inf);
    78     cout<<ans<<endl;
    79     //fclose(stdin);
    80     //fclose(stdout);
    81     return 0;
    82 }
    View Code

    wyh大聚聚的代码:300ms比我快多了TAT

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<set>
     9 #include<map>
    10 #include<bitset>
    11 #include<vector>
    12 using namespace std;
    13 #define PA pair<int,int>
    14 const int N=0,M=0;
    15 inline int read()
    16 {int s=0,f=1;char ch=getchar();
    17  while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    18  while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
    19  return s*f;
    20 }
    21 int n,np,x[505][505],S,T,h[505][505],d[130005];long long ans;
    22 int be[130005],bv[2000005],bl[2000005],bn[2000005],bw=1;
    23 void put(int u,int v,int l)
    24 {++bw;bn[bw]=be[u];be[u]=bw;bv[bw]=v;bl[bw]=l;}
    25 void in()
    26 {scanf("%d",&n);
    27  for(int i=1;i<=n;i++)
    28     for(int j=1;j<=n;j++)
    29        {int s=read();
    30         x[max(i,j)][min(i,j)]+=s;
    31         if(i!=j)ans+=s;
    32        }
    33  for(int i=1;i<=n;i++)
    34     for(int j=1;j<=i;j++)
    35        h[i][j]=++np;
    36  S=++np,T=++np;
    37  for(int i=1;i<=n;i++)
    38     {x[i][i]-=read();
    39      if(x[i][i]>0)ans+=x[i][i];
    40      else put(S,h[i][i],x[i][i]*-1),put(h[i][i],S,0);
    41     }
    42  for(int i=1;i<=n;i++)
    43     {for(int j=1;j<i;j++)
    44         put(h[i][i],h[i][j],min(x[i][i]*-1,x[i][j])),put(h[i][j],h[i][i],0);
    45      for(int j=i+1;j<=n;j++)
    46         put(h[i][i],h[j][i],min(x[i][i]*-1,x[j][i])),put(h[j][i],h[i][i],0);
    47     }
    48  for(int i=1;i<=n;i++)
    49     for(int j=1;j<i;j++)
    50        if(x[i][j])
    51          put(h[i][j],T,x[i][j]),put(T,h[i][j],0);
    52 }
    53 int dfs(int x,int sum)
    54 {
    55  if(x==T)return sum;
    56  int ans=0,f=0;
    57  for(int i=be[x];i;i=bn[i])
    58     if(bl[i])
    59      if(d[bv[i]]==d[x]+1)
    60       {f=dfs(bv[i],min(sum,bl[i]));
    61        ans+=f;
    62        sum-=f;
    63          bl[i]-=f;
    64          bl[i^1]+=f;
    65        if(!sum)return ans;
    66       }
    67  return ans;
    68 }
    69 queue<int>q;
    70 int bfs()
    71 {q.push(S);
    72  for(int i=1;i<=np;i++)
    73     d[i]=5000000;
    74  d[S]=1;q.push(S);
    75  while(!q.empty())
    76    {int u=q.front();q.pop();
    77     for(int i=be[u];i;i=bn[i])
    78        if(d[bv[i]]>d[u]+1&&bl[i])
    79          {d[bv[i]]=d[u]+1;
    80           q.push(bv[i]);
    81          }
    82    }
    83  return dfs(S,500000);
    84 }
    85 int main()
    86 {
    87  freopen("algebra.in","r",stdin);
    88  freopen("algebra.out","w",stdout);
    89  in();
    90  int s=0;
    91  while(s=bfs())ans-=s;
    92  printf("%d",ans);
    93  return 0;
    94 }
    View Code

    这是我在BZOJ AC的第10题,仅此纪念  2015/6/12

  • 相关阅读:
    How to do Deep Learning on Graphs with Graph Convolutional Networks
    《编程珠玑》读书笔记
    NFFM的原理与代码
    场感知因子分解机器的原理与代码
    数学公式中的变体字母
    因子分解机原理与代码
    LightGBM GPU python版本安装
    Pytorch:使用GPU训练
    [FJOI2020]世纪大逃亡 题解
    [统一省选2020]冰火战士 题解
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/bzoj3996.html
Copyright © 2020-2023  润新知