BZOJ3996 TJOI2015 線性代數

2022-03-29 17:58:01 字數 1530 閱讀 8114

bzoj3996: [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的非負整數。

輸出最大的d

31 2 1

3 1 0

1 2 3

2 3 7

21<=n<=500

題解here!

本來以為是一道噁心數論。。。

這是個$flag$。。。

然後放了幾天後壯著膽子看題,然後那個$flag$立馬就被推翻了。。。

這不是網路流嘛。。。

由於$a$只有$0$和$1$,所以我們可以把$0$看作不取,$1$看作取。

那題目就變成了:

有$n$個點,取$i$要扣除$c_i$的收益,但同時取$i$和$j$則可以獲得$b[i][j]+b[j][i]$的收益。

這就是很經典的最小割建模,因為把一張網路分成兩部分,一部分表示取,另一部分表示不取,最小割就是這個方案的收益。

設源點$s$,匯點$t$。

用$(i,j)$表示同時選$i$和$j$,$s$向$(i,j)$連流量為$b[i][j]+b[j][i]$的邊。

用$i$表示不選$i$,$i$向$t$連容量為$c[i]$的邊。

為了保證$(i,j)$和$i,j$同時選擇,$(i,j)$分別向$i$和$j$連流量為無限大的邊。

這樣,跑一遍最大流,$\text$就是答案了。

附**:

#include#include#include#include#define maxn 200010

#define maxm 510

#define max 999999999

using namespace std;

int n,m,s,t,c=2;

long long sum=0;

int head[maxn],deep[maxn],b[maxm][maxm];

struct edgea[maxn*10];

inline int read()

while(c>='0'&&c<='9')

return date*w;

}inline void add(int u,int v,int w)

bool bfs()

} }return false;

}int dfs(int x,int limit)

else deep[v]=-1;

} }return cost;

}int dinic()

void work()

void init()

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

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

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

}int main()

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