bzoj1975 Sdoi2010 魔法豬學院

2022-08-22 21:21:09 字數 2135 閱讀 6181

傳送門:

思路:可以用a*做,但是要手寫堆或者用pb_ds的堆,不然會被卡空間

(原題256m,bzoj64m...)

設出發點為s,結束點為t,邊權為val(e),邊的出發點為head(e),到達點為tai(e)

也可以用**方法,參見俞鼎力的《堆的可持久化和k短路》**

首先我們建出最短路樹,如果有多條任取一條以保證其樹形結構

那麼這棵樹就是乙個以結束點t為根的樹

對於圖中每條邊e,定義它的偏離值delta(e)=val(e)+dis(tail(e),t)-dis(head(e),t)

表示換成這條邊後,路徑長度會增加多少

我們定義一條路徑p中不在最短路徑樹中的邊按從s到t的順序構成的序列為s(p)

那麼路徑p的長度就是最短路長+p中所有邊的偏離值

並且該序列中相鄰兩條邊e,f滿足head(f)是tail(e)在最短路徑樹上的祖先(包括自己)

這個性質很顯然,相鄰兩條邊之間只會有樹邊或者沒有其他邊,樹邊又總是從兒子指向父親

然後我們要證明,滿足該條件的序列和一條路徑是一一對應的

這個也比較顯然,兩點間的樹上路徑當然只有一條

現在的問題就是求權值第k小這種序列

用乙個優先佇列維護,每個節點記錄兩個值,路徑長度和結束點,

初始加入乙個空序列,表示最短路

我們對每個點建立乙個堆,儲存所有以該點及該點祖先出發的邊,因為序列要滿足上面的性質

怎樣得到乙個新序列呢

我們可以把當前邊替換成堆中的次大邊,也可以新加入一條該邊結束點的堆中的邊以得到乙個新序列

觀察發現,複雜度在建立每個點的堆上

但我們並不需要這麼做

樹上兒子節點的堆只是在樹上父親節點的堆的基礎上多加了一些邊而已

所以寫個可持久化的堆就可以了

(卡空間真是喪心病狂....,動態調整了一發可持久化堆的大小才卡過...)

upd:可持久化堆大小可以縮到maxm的4.5倍,空間只有30m左右,媽媽再也不用擔心我被卡空間了..

#include#include#include#include#include#include#include#define pi pair#define mp(a,b) make_pair(a,b)

#define fi first

#define se second

#define pb(a) push_back(a)

const int maxn=5010,maxm=200010;

const double eps=1e-8;

using namespace std;

int n,m,pre[maxm],now[maxn],son[maxm],tot,fa[maxn],root[maxn],ans=1;double maxv,val[maxm],dis[maxn],mind;bool vis[maxn];

struct edgee[maxm];

priority_queue,greater> q;//用來記錄所有序列的堆,first是偏離值之和,second是結束節點

void add(int a,int b,double c)

bool is0(double a)t[(int)(maxm*9)];

void read(int &x)

struct tltree;

return tot;

} int merge(int x,int y)

while (!q.empty()) q.pop();

mind=dis[1];

}}opp;

void dfs(int x)

} for (int y=opp.now[x];y;y=opp.pre[y])

}int main()

int ed=t[now.se].ed;

if (root[ed]) q.push(mp(now.fi+t[root[ed]].val,root[ed]));//也可以多加一條合法的不在最短路徑樹中的邊得到k+1短

} printf("%d\n",ans);

return 0;}/*

4 6 14.9

1 2 1.5

2 1 1.5

1 3 3

2 3 1.5

3 4 1.5

1 4 1.5

*/

1975 Sdoi2010 魔法豬學院

題目鏈結 題目大意 找出1 k短路 題解 x的估價函式f x 取x到結束節點的最短路,這個是準確值,因此複雜度 按廣搜的方式擴充套件節點,每次優先擴充套件估價 實際最小的節點 第i次擴充套件到目標節點,代表找到了第i短路 我的收穫 org include include include includ...

BZOJ 1975 魔法豬學院(K短路)

題意 給出乙個帶權有向圖。求乙個最大的k使得前k短路的長度之和不大於給定的值sum。思路 首先,求出每個點到n的最短路。接著,使用優先佇列,節點為 d,u 首先將 dis 1 1 進隊。由於d在任意時候為一條1到n的路徑的長度,那麼對於邊,d dis u w dis v 為一條新的路徑的長度。vec...

BZOJ 1975 魔法豬學院(A 手寫堆)

time limit 10 sec memory limit 64 mb submit 1941 solved 595 submit status discuss ipig在假期來到了傳說中的魔法豬學院,開始為期兩個月的魔法豬訓練。經過了一周理論知識和一周基本魔法的學習之後,ipig對豬世界的世界本...