zoukankan      html  css  js  c++  java
  • BZOJ3996:[TJOI2015]线性代数(最大权闭合子图)

    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

    Solution

    没有发现选择一个$a_i$就将花费$c_i$,选择$a_i$和$a_j$将收益$b_{i,j}$,然后就成了最大权闭合子图了。

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<queue>
     5 #define N (1009)
     6 using namespace std;
     7 
     8 struct Edge{int to,next,flow;}edge[2*N*N];
     9 int n,b[N][N],c[N],Depth[2*N*N],INF,s,e=1e6,sum;
    10 int head[2*N*N],num_edge;
    11 queue<int>q;
    12 
    13 void add(int u,int v,int l)
    14 {
    15     edge[++num_edge].to=v;
    16     edge[num_edge].next=head[u];
    17     edge[num_edge].flow=l;
    18     head[u]=num_edge;
    19 }
    20 
    21 int DFS(int x,int low)
    22 {
    23     if (x==e || !low) return low;
    24     int f=0;
    25     for (int i=head[x]; i; i=edge[i].next)
    26         if (Depth[edge[i].to]==Depth[x]+1)
    27         {
    28             int Min=DFS(edge[i].to,min(low,edge[i].flow));
    29             edge[i].flow-=Min;
    30             edge[((i-1)^1)+1].flow+=Min;
    31             f+=Min; low-=Min;
    32             if (!low) break;
    33         }
    34     if (!f) Depth[x]=-1;
    35     return f;
    36 }
    37 
    38 bool BFS(int s,int e)
    39 {
    40     memset(Depth,0,sizeof(Depth));
    41     Depth[s]=1; q.push(s);
    42     while (!q.empty())
    43     {
    44         int x=q.front(); q.pop();
    45         for (int i=head[x]; i; i=edge[i].next)
    46             if (!Depth[edge[i].to] && edge[i].flow)
    47             {
    48                 Depth[edge[i].to]=Depth[x]+1;
    49                 q.push(edge[i].to);
    50             }
    51     }
    52     return Depth[e];
    53 }
    54 
    55 int Dinic(int s,int e)
    56 {
    57     int ans=0;
    58     while (BFS(s,e))
    59         ans+=DFS(s,INF);
    60     return ans;
    61 }
    62 
    63 int main()
    64 {
    65     memset(&INF,0x7f,sizeof(INF));
    66     scanf("%d",&n);
    67     for (int i=1; i<=n; ++i)
    68         for (int j=1; j<=n; ++j)
    69             scanf("%d",&b[i][j]), sum+=b[i][j];
    70     for (int i=1; i<=n; ++i)
    71         scanf("%d",&c[i]);
    72     for (int i=1; i<=n; ++i)
    73         for (int j=1; j<=n; ++j)
    74         {
    75             add(s,(i-1)*n+j,b[i][j]);
    76             add((i-1)*n+j,s,0);
    77         }
    78     for (int i=1; i<=n; ++i)
    79         for (int j=1; j<=n; ++j)
    80         {
    81             add((i-1)*n+j,n*n+i,INF);
    82             add(n*n+i,(i-1)*n+j,0);
    83             add((i-1)*n+j,n*n+j,INF);
    84             add(n*n+j,(i-1)*n+j,0);
    85         }
    86     for (int i=1; i<=n; ++i)
    87     {
    88         add(n*n+i,e,c[i]);
    89         add(e,n*n+i,0);
    90     }
    91     printf("%d
    ",sum-Dinic(s,e));
    92 }
  • 相关阅读:
    Ubuntu下cc和gcc的关系
    Ubuntu下makefile的简单使用
    Ubuntu下配置Apache以及搭载CGI
    Easy C 编程 in Linux
    Ubuntu下配置GitHub
    Ubuntu学习之路2
    Ubuntu下配置Java环境
    Vim学习之路1
    将博客搬至CSDN
    ubuntu连接手机的方法
  • 原文地址:https://www.cnblogs.com/refun/p/10288360.html
Copyright © 2011-2022 走看看