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,接下来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



根据乘法分配律可知,对于$b(i,j)$ ,只有$a[i],a[j]$ 都选才会有贡献。

而选择$a[j]$会导致选择$-c[j]$.

可以发现这是个最大权闭合子图的模型。

$S->b[i][j],b[i][j]->c[i],b[i][j]->c[j],c[i]->T$

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 300050
#define M 2000050
#define inf 100000000
int head[N],to[M],nxt[M],flow[M],cnt=1,sum,n;
int dep[N],Q[N],l,r,S,T,idx[510][510],c[510];
inline void add(int u,int v,int f) {
    to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f;
    to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0;
}
bool bfs() {
    memset(dep,0,sizeof(dep));
    l=r=0;Q[r++]=S;dep[S]=1;
    while(l<r) {
        int x=Q[l++],i;
        for(i=head[x];i;i=nxt[i]) {
            if(!dep[to[i]]&&flow[i]) {
                dep[to[i]]=dep[x]+1;
                if(to[i]==T) return 1;
                Q[r++]=to[i];
            }
        }
    }
    return 0;
}
int dfs(int x,int mf) {
    if(x==T) return mf;
    int i,nf=0;
    for(i=head[x];i;i=nxt[i]) {
        if(dep[to[i]]==dep[x]+1&&flow[i]) {
            int tmp=dfs(to[i],min(mf-nf,flow[i]));
            if(!tmp) dep[to[i]]=0;
            nf+=tmp;
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            if(nf==mf) break;
        }
    }
    return nf;
}
void dinic() {
    int f;
    while(bfs()) while(f=dfs(S,inf)) sum-=f;
    printf("%d\n",sum);
}
int main() {
    int i,j,x;
    scanf("%d",&n);
    S=n*n+n+1;T=S+1;
    int tot=0;
    for(i=1;i<=n;i++) {
        for(j=1;j<=n;j++) {
            idx[i][j]=++tot;
            scanf("%d",&x);
            sum+=x;
            add(S,tot,x);
        }
    }
    for(i=1;i<=n;i++) {
        scanf("%d",&c[i]);
        add(i+n*n,T,c[i]);
    }
    for(i=1;i<=n;i++) {
        for(j=1;j<=n;j++) {
            add(idx[i][j],n*n+i,inf);
            add(idx[i][j],n*n+j,inf);
        }
    }
    dinic();
}

原文地址:https://www.cnblogs.com/suika/p/8998171.html

时间: 2024-11-03 18:09:37

BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图的相关文章

BZOJ_4873_[Shoi2017]寿司餐厅_最大权闭合子图

题意:http://www.lydsy.com/JudgeOnline/problem.php?id=4873 分析:我们发现分数正负都有,并且之间有依赖关系,很容易想到最大权闭合子图. 建图: 1.S向正点连边,负点向T连边. 2.选了[i~j]显然要选[i+1~j]和[i~j-1],分别连边. 3.对于i==j的点,向对应的寿司连边. 4.总花费m*x*x+c*x拆成两部分.对于每个代号x,向T连容量为m*x*x的边,c*x这部分我们考虑算f[i][i]时把f[i][i]的值减掉x,当然也可

b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子图

b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子 题意:n*m个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求获得的最大分数. 分析:把每个植物向能保护它的植物连边.源点连正权点,负权点连汇点. 考虑在一个环上的植物是吃不到的,我们可以用拓扑排序确定哪些是能吃的. 然后求一遍最大权闭合子图就是答案. 代码: 1 #include <stdio.h> 2 #include <string.h>

bzoj 3996 线性代数 —— 最大权闭合子图

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3996 把题中的式子拆开看看,发现就是如下关系: 如果 a[i] == 1 && a[j] == 1,则 b[i][j] 有贡献: 如果 a[i] == 1,则 -c[i] 有贡献: 所以就是最大权闭合子图的模型,b[i][j] 向 a[i] 和 a[j] 连边,a[i] 向 c[i] 连边: 而 c[i] 这个点实际上没什么用,直接变成 a[i] 向 T 连边,边权是 c[i] 即可

HDU5772 String problem(最大权闭合子图)

题目..说了很多东西 官方题解是这么说的: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得分) 第二类:原串中的n个点每个点拆出一个点,第i个点权值为 –a[s[i]] (表示要花费) 第三类:对于10种字符拆出10个点,每个点的权值为  -(b[x]-a[x]) 那么我们可以得到一个关系图 ,对于第一类中的点Pij,如果想要选择Pij,你就必须要选中第二类中的点i和j,对于第二类中的点如果你想选中第i个点,其对应的字

[BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1497 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以考虑最大权闭合子图 假设a与b之间有权值为c的边(根据题意是双向边) 那么我们可以建一个新节点,点的权值为c,并指向a点和b点(单向),同时断掉原本a,b之间的双向边,a,b的点的权值是它们的花费(负的) 那么对于原问题就转化成了求最大权闭合子图的问题了 ——————————————————————

NOI2006 最大获利(最大权闭合子图)

codevs 1789 最大获利 2006年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目描述 Description 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是 挑战.THU 集团旗下的 CS&T 通讯公司在新一代通讯技术血战的前夜,需要做 太多的准备工作,仅就站址选择一项,就需要完成前期市场研究.站址勘测.最 优化等项目. 在前期市场调查和站址勘测之后,公司得到了一共 N 个可以作为通讯信号中 转站的地址,而由于这些地址的地理位置差异,在不同

hiho一下 第119周 #1398 : 网络流五&#183;最大权闭合子图 【最小割-最大流--Ford-Fulkerson 与 Dinic 算法】

#1398 : 网络流五·最大权闭合子图 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编号1..M),邀请编号为i的同学来参加班级建设活动需要消耗b[i]的活跃值. 每项活动都需要某些学生在场才能够进行,若其中有任意一个学生没有被邀请,这项活动就没有办法进行. 班级建设的活

hdu 3996 Gold Mine 最大权闭合子图

Gold Mine Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2374    Accepted Submission(s): 514 Problem Description Long long ago, there is a gold mine.The mine consist of many layout, so some are

CF 103E Buying Sets 最大权闭合子图,匹配 难度:4

http://codeforces.com/problemset/problem/103/E 这道题首先一看就很像是最大权闭合子图,但是我们可以认为现在有两种点,数字和集合点,我们需要消除数字点的影响才能直接运用最大权闭合子图. 进行二分匹配,使得每个集合都唯一匹配一个数字,买下一个集合点,则意味着该集合中所有数字的对应匹配集合点都要被买下,也就是可以建立一个新图,其中某个集合点向对应数字代表的集合点连单向边,可以证明对于任意权闭合子图中的集合点,集合中所有数字的对应匹配集合点都已经在这个权闭合