P1967 貨車運輸 生成樹 LCA

2022-04-30 21:33:17 字數 1404 閱讀 1427

a國有n座城市,編號從 1到n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q* 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。

看我蒻到把雙向邊連成單向邊debug了一上午。

很顯然,如果只有乙個詢問,我們貪心地連邊直到起點和終點連通即可。如果有這麼多個詢問,我們仍然可以像最小生成樹那樣如法炮製,貪心地搞乙個「最大生成樹」出來(我也不知道有沒有),然後你甚至可以樹剖。然後我們就在樹上亂搞,隨便用一種演算法求出樹上任意兩點之間路徑的最小權值就行了。

這裡我用到了樹上倍增求lca,分別統計兩個點到它們lca的最小權值,對這兩個值再取min就是最終答案。

#include#include#include#include#include#include#include#include#include#include#define n 500010

#define inf 0x7fffffff

#define in freopen("data.in","r",stdin);

using namespace std;

inline int read()

while(c>='0'&&c<='9')

return x*f;

}struct nodea[n];

struct recg[n];

int head[n],tot;

int fa[n],f[30][n],w[30][n],d[n],n,m;//f[i][x]表示x節點的2^i輩父親,w[i][x]表示x節點到其2^i輩父親的最小權值,d[x]表示節點x的深度

queueq;

inline void add(int x,int y,int val)

inline int get(int x)

inline void merge(int x,int y)

inline void init(int x)//bfs預處理f,w

q.push(y);

} }}inline int calc(int x,int y)//倍增求lca

if(x==y) return ans;

ans=min(ans,min(w[0][x],w[0][y]));

return ans;

}bool cmp(node a,node b)

int main()

memset(w,0x3f,sizeof(w));

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

if(!d[i]) init(i);//可能出現森林

q=read();

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

printf("%d\n",calc(u,v));

} return 0;

}

P1967 貨車運輸 LCA 生成樹

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

P1967 貨車運輸

題目 題目描述 aa國有n n座城市,編號從 1 1到 nn,城市之間有 mm 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 qq 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入格式 第一行有兩個用乙個空格隔開的整數 n,mn,m,表示 aa 國...

P1967 貨車運輸

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