bzoj3996 TJOI2015 線性代數

2022-08-13 23:30:20 字數 1278 閱讀 5026

給出乙個 n*n 的矩陣b和乙個 1*n 的矩陣c。求出乙個 1*n 的01矩陣a.使得

d=(a*b-c)*at最大。其中at為a的轉置。輸出d

第一行輸入乙個整數n,接下來n行輸入b矩陣,第i行第j個數字代表bij.

接下來一行輸入n個整數,代表矩陣c。矩陣b和矩陣c中每個數字都是不超過1000的非負整數。

輸出最大的d

1 2 1

3 1 0

1 2 3

2 3 7

1<=n<=500

把d=(a*b-c)*a^t化簡一下得出

\(d= \sum\)

\(b_a_ia_j\) - \(\sum\)

\(c_ia_i\)

由於a為01矩陣,所以可將原問題考慮成每乙個 \(a_i\) 是否選的問題

若要選 \(a_i\) 與 \(a_j\) ,即在最終答案中加上 \(b_\) ,必須在答案中減去 \(c_i\) 與 \(c_j\)

可以發現這是乙個「最大權閉合圖」問題

將 \(b_\) 及 \(c_i\) 當做節點,點權即為 \(b_\) 及 \(c_i\) 的值。

#include#include#include#define inf 200000000

using namespace std;

typedef long long ll;

const int n = 505;

const int m = 505*505+505;

struct nodepool[n*n*8+n*2],*h[m];

int cnt;

void addedge(int u,int v,int f)

int s,t;

int level[m];

int que[m];

bool bfs()

if(level[t]!=-1) return true;

}return false;

}int find(int u,int f)

}if(!s) level[u]=-1;

return s;

}int dinic()

int b[n][n],c[n];

int n;

int main()

for(int i=1;i<=n;i++)

addedge(n*n+i,t,c[i]);

sum-=dinic();

printf("%d\n",sum);

return 0;

}

BZOJ 3996 TJOI2015 線性代數

給出乙個n n的矩陣b和乙個1 n的矩陣c。求出乙個1 n的01矩陣a.使得 d a b c a t最大。其中a t為a的轉置。輸出d 第一行輸入乙個整數n,接下來n行輸入b矩陣,第i行第j個數字代表bij.接下來一行輸入n個整數,代表矩陣c。矩陣b和矩陣c中每個數字都是不超過1000的非負整數。輸...

bzoj3996 TJOI2015 線性代數

首先轉化題目 給你n 個物品,可以選或不選。選第i 個物品需要c i 的代價。同時選第 i 和第 j個物品獲得b i j 的收益 問最大收益。網路流建圖 考慮s um ni 1 nj 1b i j 剩下就變成了算代價最小 也就是最小割 建點 i,j 和i,對於每個點 i j 向 i,j 連一條容量為...

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中每個...