• P3973 [TJOI2015]线性代数


    题意描述:

    洛谷

    给你一个 (n imes n) 的矩阵 (B) 和一个 (1 imes n) 的矩阵 (C) , 让你求一个 (1 imes n)(01) 矩阵 (A), 使得: (D = (A imes B - C) imes A^T) 的值最大,输出这个最大值。

    注: (A^T)(A) 的转置,也就是将 (A) 的行和列交换后得到的矩阵。

    数据范围: (nleq 500) .

    solution:

    乍一看,可能一点思路都没有。

    我们先把求和的式子展开:

    [(A imes B-C) imes A^T\ = A imes B imes A^T - C imes A^T\ = displaystylesum_{i=1}^{n}sum_{j=1}^{n} A_iA_jB_{ij} - sum_{i=1}^{n} C_iA_i ]

    然后你会发现,当 (A_i = 1) 的代价为 (C_i)(A_i)(A_j) 同为 (1) 的时候收益为 (B_{ij}) .

    这就是一个最大权闭合子图的模型。

    建图:

    • 对于每一个 (b_{ij}), 新建一个点 (u) ,表示这一组合。由 (s)(u) 连一条容量为 (b_{ij}) 的边,由 (u) 分别向右侧的· (i)(j) 两个点连一条容量为 (inf) 的边。
    • 由右侧的点 (i) 向汇点连一条容量为 (c_i) 的边

    最后 (b_{ij}) 之和减去最小割就是答案。

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int inf = 1e7+10;
    const int N = 1e6+10;
    int n,cnt,sum,ans,s,t,tot = 1;
    int head[N],dep[N],c[N],b[1010][1010],id[1010][1010];
    struct node
    {
    	int to,net,w;
    }e[N<<1];
    inline int read()
    {
        int s = 0, w = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
        while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
        return s * w;
    }
    void add(int x,int y,int w)
    {
    	e[++tot].to = y;
    	e[tot].w = w;
    	e[tot].net = head[x];
    	head[x] = tot;
    }
    bool bfs()
    {
    	queue<int> q;
    	for(int i = 0; i <= t; i++) dep[i] = 0;
    	q.push(s); dep[s] = 1;
    	while(!q.empty())
    	{
    		int x = q.front(); q.pop();
    		for(int i = head[x]; i; i = e[i].net)
    		{
    			int to = e[i].to;
    			if(e[i].w && !dep[to])
    			{
    				dep[to] = dep[x] + 1;
    				q.push(to);
    				if(to == t) return 1;
    			}
    		} 
    	}
    	return 0;
    }
    int dinic(int x,int flow)
    {
    	if(x == t || !flow) return flow;
    	int rest = flow, val = 0;
    	for(int i = head[x]; i && rest; i = e[i].net)
    	{
    		int to = e[i].to;
    		if(!e[i].w || dep[to] != dep[x] + 1) continue;
    		val = dinic(to,min(rest,e[i].w));	
    		if(val == 0) dep[to] = 0;
    		e[i].w -= val, e[i^1].w += val, rest -= val;
    	} 
    	return flow - rest;
    } 
    int main()
    {
    	n = read();
    	for(int i = 1; i <= n; i++)
    	{
    		for(int j = 1; j <= n; j++)
    		{
    			b[i][j] = read();
    			id[i][j] = ++cnt;
    		}
    	}
    	for(int i = 1; i <= n; i++) c[i] = read();
    	s = 0, t = cnt + n + 1;
    	for(int i = 1; i <= n; i++)//建图
    	{
    		for(int j = 1; j <= n; j++)
    		{
    			sum += b[i][j]; 
    			add(s,id[i][j],b[i][j]), add(id[i][j],s,0);
    			add(id[i][j],cnt+i,inf), add(cnt+i,id[i][j],0);
    			add(id[i][j],cnt+j,inf), add(cnt+j,id[i][j],0);
    		}
    	}
    	for(int i = 1; i <= n; i++) add(cnt+i,t,c[i]), add(t,cnt+i,0);
    	int flow = 0;
    	while(bfs())
    	{
    		while(flow = dinic(s,inf)) ans += flow;
    	} 
    	printf("%d
    ",sum-ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Winform学习笔记
    ASP.NET后台注册javascript脚本方法
    使用MultipleActiveResultSets复用Sql Server 2008数据库连接
    angular 2 新建组件命令
    一个关于日志操作方法
    vs2017 打开包管理器 (程序包管理控制台)
    Asp.Net Core Identity 怎么获取当前登录的用户信息?
    abp 实现所有审计的接口
    IIS8.5 布署 Asp.Net Core 老是报500的错误怎么办?
    .NET Core 1.1布署后出现“HTTP Error 502.5 Process Failure”的解决办法
  • 原文地址:https://www.cnblogs.com/genshy/p/14409497.html
Copyright © 2020-2023  润新知