傳送門
不愧是noip2013tg的題目。
solution:
為了讓車獲得最大的載重,他們走的路徑一定是這個圖的最大生成樹上的路徑。
那麼建樹,問題轉化為查詢樹上兩點間路徑上每條邊的邊權的最小值。
這不就是樹剖的板子?但是我們發現這並不是維護點權,是維護邊權。
仔細思考發現,我們可以將每條邊的邊權轉到其深度較大的點上(即賦值到兒子上)。
只需要在對樹進行操作的時候(如用樹剖求兩點間所經過路徑的最小值)要注意避開lca
(x,y
)lca(x, y)
lca(x,
y)這個點。因為這個點代表的是lca
(x,y
)lca(x, y)
lca(x,
y)與其父親之間的邊,不應算入答案內。即在dfs
dfsdf
s序上操作的時候應該不計其深度最低的一點。
當然我們發現,這題並不要求修改邊權。那麼我們也可以用樹上倍增預處理最值。原理與rmq相像?
code:
// 這題使用rmq求dfs序上的最小值,反正題目不要求修改。
#include
#include
#include
using
namespace std;
const
int maxn =
100007
;const
int logn =20;
const
int inf =
99999999
;int n, m, q;
int value[maxn]
;struct edge
edge (
int u =0,
int v =0,
int w =0,
int nxt =0)
:u(u),
v(v),w
(w),
nxt(nxt)
}e_for[maxn]
, e[maxn]
;int fir[maxn]
, tote;
int father[maxn]
;int book[maxn]
, dep[maxn]
, siz[maxn]
, son[maxn]
, fa[maxn]
, top[maxn]
, seg[maxn]
, rev[maxn]
, ti;
int lo[maxn]
, f[maxn]
[logn +2]
;void
addedge
(int x,
int y,
int z)
intfind
(int x)
void
kruscal()
}void
dfs1
(int x,
int fath,
int col)
son[x]
= mxid;
}void
dfs2
(int x,
int topr)
}void
rmq(
)int
query
(int l,
int r)
intquery
(int x,
int y)
if(x == y)
return mx;
if(dep[x]
< dep[y]
)swap
(x, y)
; mx =
min(mx,
query
(seg[y]+1
, seg[x]))
;return mx;
}int
main()
sort
(e_for +
1, e_for + m +1)
;kruscal()
;int col =0;
for(
int i =
1; i <= n; i++)if
(!book[i]
)dfs1
(i, i,
++col)
;for
(int i =
1; i <= n; i++)if
(!top[i]
)dfs2
(i, i)
;for
(int i =
1; i <= n *
2; i++
)rmq()
; cin >> q;
for(
int i =
1; i <= q; i++
)return0;
}
洛谷 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...