最短路(hdu4725)(建點巧妙)

2022-05-07 01:15:08 字數 1311 閱讀 3770

傳送門

題目大意是:

有一些點,分為幾層,然後層與層之間可花費代價c到達,還有一些特殊邊,使得某個點和某個點之間花費某代價可以到達,求從1到n的最小代價。

一開始的想法是,既然層與層之間可以到達,那麼對於第i層和第i+1層,把第i層的所有點與第i+1層的所有點連邊,權值為c,特殊的邊該怎麼連怎麼連,然後跑最短路。

然後我看了一下資料範圍——n, m (0 <= n, m <= 105)  笑不出來

好吧,那讓我們考慮一下如何優化。

我們知道,同一層內的點是可以相互到達的且無花費。也就是說,如果我想去到第i層,我到達第i層的某個點後就相當於我到了這一層中所有的點

那麼對於每一層,我可以建乙個入點和乙個出點(或者說就建乙個點也行,反正連進和連出的邊的性質是一樣的)。層與層之間就有建的點相連(代價就為c),層內的點全部連向建的點(代價為0)。

連變數:2*n+m   時間o(e loge)能過

注意:1.建的虛擬點的編號一定不要和原來的點重複了。2.圖中的點不再是n個,而應該建成3n個

#include #include 

#include

#include

#define n 100003

#define m 100003

using

namespace

std;

intread()

while(s>='

0'&&s<='9')

return x*f;

}const

int inf=0x3f3f3f3f

;struct

qnode

bool

operator

};struct

edge

};vector

e[n*2+m];

bool vis[n*3

];int dist[n*3];

void dij(int n,int start)//

點的編號從1開始

}}}

void add(int u,int v,int

w)int

main()

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

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

dij(

3*n,1

); printf(

"case #%d: %d\n

",k,(dist[n]==inf?-1

:dist[n]));

}} /*

*/

最短路(hdu4725)(建點巧妙)

HDU 5521 巧妙地最短路

題意 n個點,m塊,塊的意思就是說,在塊中的點任意兩點的距離都是t,問分別從1點和n點走到某個點,這個點的花費就是二者較大的,問這n個點花費最小是多少,並按字典序列印序號 思路 這題頭疼的就是不知道怎麼建圖,暴力建圖會超記憶體,有乙個巧妙的方法是 將這個塊中的點全部連到乙個點上,每條邊花費t 2,這...

HDU 5521 Meeting 拆點 最短路

題目鏈結 給m個由圖中結點組成的點集,點集中的點兩兩連通且距離為相等的ti。現有兩人分別從1和n點處同時出發嗎,問能否相遇以及相遇的最短時間。很容易想到直接分別以點1和點n為起始點求最短路,再遍歷各個點即可求得最短相遇時間。然而建圖上卻有問題 這個題中的邊是以點集的形式給出,極端情況下可能會出現有1...

HDU 5521 Meeting 拆點 最短路

題目鏈結 給m個由圖中結點組成的點集,點集中的點兩兩連通且距離為相等的ti。現有兩人分別從1和n點處同時出發嗎,問能否相遇以及相遇的最短時間。很容易想到直接分別以點1和點n為起始點求最短路,再遍歷各個點即可求得最短相遇時間。然而建圖上卻有問題 這個題中的邊是以點集的形式給出,極端情況下可能會出現有1...