zoukankan      html  css  js  c++  java
  • BZOJ3996 线性代数

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3996

    转化题目给的条件

    $$D = sum_{i=1}^n sum_{j=1}^n{A(i)A(j)B(i,j)} - sum_{i=1}^n C(i)A(i)$$

    网络流可解,如果要得到 $B(i,j)$ 的话必须选$i$物品和$j$物品然后,选择每一个物品都有其代价。

    最大权闭合子图。

    再流网络中割掉一条边就是舍弃一个$B(i,j)$

    所以最小割即可。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    #define N 1100010
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    struct edge{
        int x,to,cap;
    }E[N<<2];
    
    int n,B[1010][1010],C[N],totE,g[N],S,T,h[N],tot;
    queue<int> q;
    bool v[N];
    
    #define p E[i].x
    
    void ade(int x,int y,int cap){
        E[++totE]=(edge){y,g[x],cap}; g[x]=totE;
        E[++totE]=(edge){x,g[y],0};   g[y]=totE;
    }
    
    bool bfs(){
        memset(v,0,sizeof(v));
        q.push(S); h[S]=1; v[S]=1;
        while(!q.empty()){
            int x=q.front(); q.pop();
            for(int i=g[x];i;i=E[i].to)
                if(E[i].cap&&!v[p]){
                    h[p]=h[x]+1;
                    q.push(p); v[p]=1;
                }
        }
        return v[T];
    }
    
    int dinic(int x,int flow){
        if(x==T||!flow) return flow;
        int f=0;
        for(int i=g[x];i&&flow;i=E[i].to)
            if(h[p]==h[x]+1&&E[i].cap){
                int tmp=dinic(p,min(flow,E[i].cap));
                E[i].cap-=tmp; E[i^1].cap+=tmp;
                f+=tmp; flow-=tmp;
            }
        if(!f) h[x]=-1;
        return f;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1,j;i<=n;i++)
            for(j=1;j<=n;j++) scanf("%d",&B[i][j]);
        for(int i=1;i<=n;i++) scanf("%d",&C[i]);
        S=n*n+n+1; T=S+1;
        for(int i=1;i<=n;i++) ade(i,T,C[i]);
        int ans=0;
        tot=n;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                ans+=B[i][j];
                ade(S,++tot,B[i][j]);
                ade(tot,j,INF);
                ade(tot,i,INF);
            }
        while(bfs()) ans-=dinic(S,INF);
        printf("%d
    ",ans);
        return 0;
    }
    View Code

     看来真的需要补线性代数呀。

  • 相关阅读:
    mysql 快速生成百万条测试数据
    解决mysql插入数据l出现"the table is full"的问题
    php 判断设备是手机还是平板还是pc
    golang格式化输出-fmt包用法详解
    阿里云用smtp无法发送邮件
    百度文本编辑器的toolbars属性值描述
    beego register db `default`, sql: unknown driver "mysql" (forgotten import?)
    MQ知识点汇总
    redis知识点汇总
    知识体系
  • 原文地址:https://www.cnblogs.com/lawyer/p/4551341.html
Copyright © 2011-2022 走看看