題目是給了你乙個spfa+slf優化的程式,然後,讓你造個資料卡掉他,
其實那個slf優化根本不算是優化,只是在某些圖上可能會更好,但是可以通過直接構造圖將其由原本spfa最壞nm的複雜度卡成2^n複雜度
至於具體的,這題是曹聖 ( 給我講的,他那裡寫的很詳細,我就直接copy了
在這個圖中,我們設計算從i到n的最短路所需要的運算次數為f(i),則對於奇數號點p,如1,3,..,n,會把p+1放到隊尾,把p+2放到隊首,因為p+2在隊首,所以會先從p+2開始,又因為後邊所有的邊都是非正的,所以他們不會小於p+2,即他們也會放到隊首。這樣我們就先計算了以下從p+2出發的一次最短路,然後在從p+1到p+2,更新了p+2的值,又重新計算了一次從p+2出發的一次最短路。這樣我們可以得出f(i)>2*f(i+2),這個遞迴式顯然是指數增長的,即只需30對點,就可以讓它的複雜度增長到2^30。
過這道題的**是這樣的..無須考慮輸入資料...
#include#includeusing namespace std;
const int t = 30;
int main()
{ int c;
while (scanf("%d",&c)!=eof)
{ int n , m , i ;
n = t * 2 + 1;
m = t * 3;
printf("%d %d\n",n,m);
for (int i = 0 ; i 究其原因,要從spfa是bellman-ford的優化說起。在n個點m條邊的圖中,bellman-ford的複雜度是n*m,依次對每條邊進行鬆弛操作,重複這個操作n-1次後則一定得到最短路,如果還能繼續鬆弛,則有負環。這是因為最長的沒有環路的路,也只不過是n個點n-1條邊構成的,所以鬆弛n-1次一定能得到最短路。
spfa的意義在於,如果乙個點上次沒有被鬆弛過,那麼下次就不會從這個點開始鬆弛。每次把被鬆弛過的點加入到佇列中,就可以忽略掉沒有被鬆弛過的點。
但是最外層的迴圈還是n-1次..如果把被鬆弛的點放到前邊,他相當於沒有進行完這一輪鬆弛,就開始了一些其他的操作。但是這些其他的操作可能是無用的,因為這些操作的起始點可能還會被這一輪鬆弛更新。
所以傳統的spfa的複雜度不會超過n*m,並且每個點都不會第n次入隊。但是slf優化...其實就不是個優化..它丟掉了一輪一輪鬆弛的這個特性..導致複雜度可能呈指數級上公升。
以上來自jinzhao1994
就是醬紫。。。>《其實我自己這次也是才知道,btw提一句,晚上的時候。。。給某梁學妹說這個題。。。被10min秒殺了,,果然厲害啊唔。。。還得努力啊。。。
HDU 3790 最短路徑 spfa
給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。input 輸入n,m,點的編號是1 n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,...
hdu 1384 spfa 差分約束
可能是因為太累了吧,早上6點睡的,spfa居然乙個vis陣列敲錯了!wa了好久。還是要多敲。細心 冷靜 這題是差分約束題,一般的差分約束是先轉換為圖,然後用spfa求其中的最短路 長的一b,沒怎麼看,我自己試著搞了搞,同樣的把這些不等式轉換為圖,然後求的不是最短路而是最長路 而且我的圖里的權值除了回...
hdu6007 spfa 完全揹包
題意 給你m,n,k,代表你有m點法力值,n個物品,k個製造方式 接下來n行,如果以1開頭則代表既能賣又能合成,0代表只能賣。然後k行,每行第乙個數是要合成的東西,第二個數代表有幾對,每對第乙個數是那種物品,第二個是需要幾個。注意不能直接合成的可以通過製造方式來合成。然後問你花費完所有的法力製造的東...