題目大意
給出n個錯誤與m種不同的補丁,每種補丁當且僅當b1[i]包含當前狀態的的錯誤,且b2[i]不包含當前狀態下的
錯誤(b1[i]與b2[1]是兩個集合,題目給出)。
每個補丁都有他自己的執行時間,i補丁會修復在f1[i]裡面的錯誤,同時也會帶來f2
[i]裡面的錯誤。(因為這個,
題目從簡單的二分圖最大匹配問題變得很複雜。至少在你沒有看出來是最短路求解之前) 解法
很多人都說這題不應該出在網路流24題裡面,因為這題用網路流做會很複雜(因為我不懂),所以大多數a了這題的人跟我一樣,都是用
最短路+狀態壓縮
求解,其實也很好解釋。
用queue[i]來作為最短路的佇列,裡面存的是乙個狀態,因為總錯誤只有20個,所以對於第k個錯誤來說,如果已經被處理過了,那麼倒數第k位就是0;否則就是1,相當於加上1<<(k-1);
很多人會說,你講那麼快,我怎麼會看的懂?妖怪吧。。
那我們來舉乙個例子比如說現在一共有5個錯誤,1錯誤被處理掉了,3錯誤也被處理掉了,那麼狀態就是11010(26)。沒錯,n<=20,所以這個東西轉成10進製之後不過才100多萬。你可以像我一樣開乙個迴圈佇列或者是系統的佇列都行,希望大家能聽懂咯。。
每一次迭代一遍補丁,找到滿足條件的補丁後,算出目標狀態,判斷當前狀態所用時間+補丁所用時間《原來花費時間,那麼就把原來時間替換掉(=當前狀態所用時間+補丁所用時間),加進佇列,繼續操作,最後判斷一下0(及所有都被處理掉時)狀態是否被查詢過,如果是,那麼輸出0狀態時間,否則就輸出0。完了。希望大家喜歡,下面的是c++**。
#include#include#includeint time[110];
int n,m;
int b1[110],b2[110],f1[110],f2[110];
int queue[1050010];
int d[1050010];
int st,ed;
void bfs()
}} st++;
if(st>105000) st=1; }}
int main()
scanf("%s",s+1);
for(int j=1;j<=n;j++)
}bfs();
if(d[0]==1061109567)
printf("0\n");
else
printf("%d",d[0]);
}
P2761 軟體補丁問題
t 公司發現其研製的乙個軟體中有 n 個錯誤,隨即為該軟體發放了一批共 m 個補丁程式。每乙個補丁程式都有其特定的適用環境,某個補丁只有在軟體中包含某些錯誤而同時又不包含另一些錯誤時才可以使用。乙個補丁在排除某些錯誤的同時,往往會加入另一些錯誤。換句話說,對於每乙個補丁 i,都有 2 個與之相應的錯...
bzoj2761 洛谷P4305 不重複數字
洛谷4305 滑稽 乙個map判一下重,如果當前這個數字還沒出現,就把它加入序列中 如果想練一下hash也是可以的 就手打乙個hash函式 vector就珂以了 所以 為什麼洛谷上是綠題啊?ps.洛谷上珂以用unordered map,會快一些,但bzoj貌似用不了qwq include inclu...
洛谷 P1190 接水問題
題目描述 學校裡有乙個水房,水房裡一共裝有 m 個龍頭可供同學們開啟水,每個龍頭每秒鐘的 供水量相等,均為 1。現在有 n 名同學準備接水,他們的初始接水順序已經確定。將這些同學按接水順序從 1到 n 編號,i 號同學的接水量為 wi。接水開始時,1 到 m 號同學各佔乙個水龍頭,並同時開啟水龍頭接...