你有足夠多的象棋「車」,在乙個n×n的棋盤上你能放多少個「車」呢?注意,所給棋盤上有些位置不能放任何東西。同時,某一行(列)最多只能存在乙個「車」。
第一行為乙個正整數n。(1<=n<=500 )
接下來n行,每行包含n個整數,若為0表示這個位置不能放「車」;若為1表示這個位置可以放「車」。
輸出乙個整數,表示最多能放多少個「車」。
5
1 0 0 0 0
0 0 0 0 0
0 0 0 1 0
1 1 0 1 0
0 0 0 1 0
3
將行看作x集合,列看作y集合
若棋盤上為1的位置有(i,j),則x集的第i個點向y集的第j個點連邊
#include
using namespace std;
const
int n =
505*
2, m= n * n;
struct ee[m]
;//ihead:鄰接表的頭
//cnt:鄰接表大小
//mc:表示每個點所匹配到的另乙個點match
//vis:y集元素是否被訪問過
int cnt,ihead[n]
,mc[n]
;bool vis[n]
;//鄰接錶連邊,表示連一條x到y的有向邊
//x:起點
//y:終點
void
add(
int x,
int y)
//匈牙利演算法
//x:x集上的點,從當前點出發找增廣路
//返回值:若找到增廣路則返回true,否則返回false
bool dfs
(int x)}}
return false;
}// 求解棋盤上最多能放多少個「車」
// n:棋盤的大小為n×n的
// board:所給棋盤,對於某個位置上的數:若值為1表示可以放「車」;若值為0表示不能放「車」
// 返回值:能放「車」的最大個數
intgetanswer
(int n, vectorint>> board)
//連邊
for(
int i =
1; i <= n;
++i)
for(
int j =
1; j <= n;
++j)
if(board[i-1]
[j-1]==
1)add(i,j+n)
;int ans =0;
for(
int i=
1; i<=n;
++i)if(
!mc[i]
)return ans;
}int
main()
e.push_back
(t);
}printf
("%d\n"
,getanswer
(n, e));
return0;
}
清華大學演算法訓練營 等式
時間限制 2s,空間256mb 問題描述 n個變數和m個 相等 或 不相等 的約束條件,請你判定是否存在一種賦值方案滿足所有m個約束條件。輸入第一行乙個整數t,表示資料組數。t 100 接下來會有t組資料,對於每組資料 第一行是兩個整數n,m,表示變數個數和約束條件的個數。1 n,m 500000 ...
清華大學演算法訓練營 重編碼
重編碼 priority queue 有一篇文章,文章包含 n種單詞,單詞的編號從 1 至 n,第 i 種單詞的出現次數為 w i 現在,我們要用乙個 2 進製串 即只包含 0 或 1 的串 s i 來替換第 i 種單詞,使其滿足如下要求 對於任意的 1 i,j n i j 都有 s i 不是 s ...
清華大學演算法訓練營 序列計數
給定乙個n個整數的序列以及乙個非負整數d,請你輸出這個序列中有多少個連續子串行 長度大於1 滿足該子串行的最大值最小值之差不大於d。如 序列1 2 3中長度大於1的連續子串行有 1 2 2 31 2 3第一行包含兩個整數n,d。1 n 300000,0 d 2000000000 接下來一行包含n個整...