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