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 ...