洛谷 P1967 貨車運輸

2021-10-24 02:14:15 字數 2019 閱讀 8589

前置知識:生成樹,並查集,倍增求lca

化簡題意:求圖上兩點之間路徑上邊權最小的邊(由於最終生成的是樹,所以路徑唯一)。注意兩點可能是不連通的。

大致:先用最大生成樹重新建邊,然後用並查集判斷一下兩點是否在同乙個聯通塊,之後用倍增在求lca的時候維護邊權的最小值

最大生成樹:由於要找邊權最小的邊,所以盡量在生成樹的時候選大邊(sort排序改一下就行了)

並查集:生成樹使用克魯斯卡爾演算法,因為從資料可以得出是稀疏圖,不建議使用皮姆演算法其實是我不會

#include

using

namespace std;

int n,m,q;

struct _edge1pe[

100007];

//原圖

struct _edge2ne[

100007];

//重新建的圖

int num_edge2,nh[

100007];

//鏈式前向星

int mst_fa[

10007];

//並查集

int bz_fa[

10007][

21],minn[

10007][

21],dep[

10007

],vis[

10007];

//倍增求lca

void

add_edge2

(int x,

int y,

int w)

;//前向星加邊

intread()

;//快讀

//mst最小生成樹部分

intmst_find_fa

(int x)

void

mst_merge

(int x,

int y)

bool

cmp(_edge1 x,_edge1 y)

void

mst()}

return;}

//mst

//dfs

void

dfs(

int now)

return;}

//dfs

//lca

intlca

(int x,

int y)}if

(x==y)

return ans;

for(

int i=

14;i>=0;

--i)

if(bz_fa[x]

[i]!=bz_fa[y]

[i])

ans=

min(ans,

min(minn[x][0

],minn[y][0

]));

//記得最後還要求一次(其實這裡[x][0]和[y][0]選乙個取最小就行了,因為已經是公共祖先)

return ans;

//最後就不是返回祖先了,而是邊權最小值

}//lca

intmain()

mst();

for(

int i=

1;i<=n;

++i)

}for

(int j=

1;j<=14;

++j)

for(

int i=

1;i<=n;

++i)

cin>>q;

for(

int i=

1;i<=q;

++i)

return0;

}//add_edge

void

add_edge2

(int u,

int v,

int w)

//add_edge

//read

intread()

while

(ch>=

'0'&&ch<=

'9')

return res*flag;

}//read

洛谷 P1967 貨車運輸

a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入檔名為 truck.in。輸入檔案第一行有兩個用乙個空格隔開的整數 n,m,表示 a 國有 ...

洛谷 P1967 貨車運輸

題目描述 a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入輸出格式 輸入格式 輸入檔名為 truck.in。輸入檔案第一行有兩個用乙個空格隔...

貨車運輸 洛谷p1967

解法一 30分 直接跑spfa,求最大瓶頸路。include include include define f i,l,r for i l i r i using namespace std const int maxn 10005,maxm 50005,inf 100000000 struct e...