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