0x68 C題 車的放置

2022-01-10 07:22:08 字數 1912 閱讀 7321

給定乙個n行m列的棋盤,已知某些格仔禁止放置。

問棋盤上最多能放多少個不能互相攻擊的車。

車放在格仔裡,攻擊範圍與中國象棋的「車」一致。

第一行包含三個整數n,m,t,其中t表示禁止放置的格仔的數量。

接下來t行每行包含兩個整數x和y,表示位於第x行第y列的格仔禁止放置,行列數從1開始。

輸出乙個整數,表示結果。
示例1

8 8 0
8
先分析出之前講的 \(0/1要素\)

「1要素」

每行、每列只能放1個車(不然就能互相攻擊到)。某個格仔 \((i,j)\) 如果放了車,就等於占用了第 \(i\) 行與第 \(j\) 列放車的「名額」

因此,我們可以把行、列看作節點,一共\(n+m\)個節點。如果格仔\((i,j)\) 沒有被禁止,就在第 \(i\)行對應的節點與第 \(j\) 行對應的節點之間連無向邊。

「0要素」:

每個車顯然不能既在第 \(i_1\) 行又在第 $ i_2$ 行,所以兩個「行」對應的節點之間沒有邊。對於「列」也同理。

因此,剛才構建的無向圖是二分圖,我們可以把n個「行節點」作為左部,m個列節點」作為右部。

更在不能互相攻擊的前提下放置的車最多,就是求上述分圖的最大匹配,時間複雜度為 \(o((n +m)*nm)\)。

ac**

#includeusing namespace std;

int n, m, t, f[210], b[210], ans;

bool a[210][210], v[210];

bool dfs(int x)

}return false;

}int main()

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

cout << ans << endl;

}

完備匹配:

給定一張二分圖,其左部、右部點數相同,均為 \(n\) 個節點。如果該二分圖的最大匹配包含 \(n\)

條匹配邊,則稱該二分圖具有完備匹配

多重匹配:

給定一張包含 \(n\) 個左部節點、\(m\) 個右部節點的二分圖。從中選出盡量多的邊,使第 \(i (1 <= i <=n)\) 個左部節點至多與 \(kl_i\) 條選出的邊相連,第 \(j(i <= j <= m)\) 個右部節點至多與 \(kr_j\) 條選出的邊相連。該問題被稱為二分圖的多重匹配。

當\(kl_i=kr_j=1\) 時,上述問題就簡化為二分圖最大匹配。因此,多重匹配是乙個廣義的「匹配」問題,每個節點可以與不止一條「匹配」邊相連,但不能超過一.個給定的限制。

多重匹配一般有 四種解決方案:

1.拆點。把第 $i $個左部節點拆成 \(kl_i\)個不同的左部節點,第j個右部節點拆成 \(kr_j\)個右部節點。對於原

圖中的每條邊 \((i,j)\), 在i拆成的所有節點與 \(j\) 拆成的所有節點之間連邊。然後求解二分圖最大匹配。

2.如果所有的 \(kl_i= 1\),或者所有的 \(kr_j= 1\),即只有一側是「多重」匹配,不妨設左部是「多重」的,那麼可以

直接在匈牙利演算法中讓每個左部節點執行 $kl_i $ 次dfs​。

3.在第2種方案中,當然也可以交換左右兩部,設「右部」是多重的,修改匈牙利演算法的實現,讓右部

節點可以匹配 \(kr_j\)次,超過匹配次數後,就要依次嘗試遞迴當前匹配的 \(kr_j\)個左部節點,看能否找到增廣路

4.網路流。這是最一般也是最高效的解決方法。但博主尚未學習(可能以後會補上)。

C 中 x與0x的區別

首先這兩個均表示16進製制,但是用法有所不同。x主要是用於字元的表示 如char ch xa 那麼ch這個字元所代表的是什麼呢?正如上面所說的 x代表的是16進製制,16進製制中的a在十進位制中代表10,那麼ch這個數就代表著序號為10的ascii碼所代表的字元,即 n換行符。0x雖然也代表十六進製...

C 0 x中 C 的未來

0 x的工作名稱的新標準c 增加了許多,我將在這一系列c 11的語言功能。2011年9月,c 0 x的正式出版為新的c 11標準,現在許多編譯器提供了一些核心c 11功能的支援。c 11包括廣泛的特點 主要的新功能,像拉姆達的支援和 移動語義 通過自動關鍵字型別推斷可用性改進,例如,簡化迴圈容器,許...

C 0x11中列舉的問題

c 11中新增的強型別列舉,確實可以解決此前版本中列舉的作用域問題,但是隨之也帶來一些其他問題。強型別列舉的宣告方式為 enum class enumname value1,value2 在編碼中,我以前比較習慣對列舉值應用位運算,比如 和 但是對於c 11中的強型別列舉,則無法再應用位運算。比如 ...