題目大意:給定 n 個點,m 條邊的無向圖,支援兩種操作:動態刪邊和查詢任意兩點之間路徑上邊權的最大值最小是多少。
題解:引理:對原圖求最小生成樹,可以保證任意兩點之間的路徑上邊權的最大值取得最小值。
證明:任取兩點 x, y,若 x, y 的路徑上最大值最小的邊不在最小生成樹的路徑上,可以將那條邊加入最小生成樹中,並刪去由這條邊的加入所帶來的環中邊權最大的那條邊,可以使得最小生成樹更小,產生矛盾,證畢。
有了引理之後,問題轉化成了維護支援動態刪邊的最小生成樹。發現刪邊可能會導致最少生成樹不斷發生變化,每次變化都需要重構生成樹,時間複雜度較高。可以採用離線詢問,轉化成倒序加邊的最小生成樹的維護,每次加一條邊時,只需刪除環上最大的那條邊即可。支援動態加邊和刪邊,可以採用 lct 進行維護。最後,可以進行點邊轉化,即:將邊縮為乙個點,邊權為點權,點的點權為 0 即可。
**如下
#include using namespace std;
struct edge
};struct ufs
} int find(int x)
bool merge(int x, int y)
return 0;
}};struct node
void unsafe_reverse()
void pull()
if (r != null)
} void push()
if (r != null)
rev = 0;
} }};bool is_root(node *v)
return (v->p == null) || (v->p->l != v && v->p->r != v);
}void rotate(node *v)
if (u == v->p->r)
} if (v == u->l)
if (v == u->r)
u->pull();
v->pull();
}void deal_with_push(node *v)
v = v->p;
} while (!stk.empty())
}void splay(node *v) else
}rotate(v);
}}void access(node *v)
}void make_root(node *v)
node *find_root(node *v)
splay(v);
return v;
}void split(node *u, node *v)
void link(node *u, node *v)
make_root(v);
v->p = u;
}void cut(node *u, node *v)
}node* find(node *v, int val)
if (v->l != null && v->l->maxv == val) else
} return v;
}int main()
vectore(m + 1);
map, int> id;
for (int i = 1; i <= m; i++)
e[i] = ;
id = i;
} vector>> events(q + 1);
for (int i = 1; i <= q; i++)
events[i] = };
if (opt == 2) ]].has = 0;
} }auto kruskal = [&](vectoree) ] + n; // edge_id
t[_id] = new node(z, _id);
link(t[x], t[_id]);
link(t[y], t[_id]);}}
} };
kruskal(e);
vectorans;
for (int i = q; i >= 1; i--) ];
int z = e[eid].z;
if (events[i].first == 1) else
} }reverse(ans.begin(), ans.end());
for (auto v : ans)
return 0;
}
洛谷P4172 WC2006 水管局長
lct動態維護最小生成樹的典例 這個都是套路,倒序處理,將刪邊變成加邊 再將邊換成點,然後就可以做到點權維護邊權資訊 說一下加邊的過程大概是 一 首先最小生成樹,保證初始最優 二 對於新加入的一條邊,找出原x y鏈上的最大邊,替換 第二點的實現比較有意思 因為是在樹上加邊,所以一定會形成乙個環,那麼...
洛谷P4172 WC2006 水管局長
sc省my市有著龐大的地下水管網路,嘟嘟是my市的水管局長 就是管水管的啦 嘟嘟作為水管局長的工作就是 每天供水公司可能要將一定量的水從x處送往y處,嘟嘟需要為供水公司找到一條從a至b的水管的路徑,接著通過資訊化的控制中心通知路徑上的水管進入準備送水狀態,等到路徑上每一條水管都準備好了,供水公司就可...
P4172 水管局長 lct維護最小生成樹
題目 a b路徑的最長邊最小 這個路徑一定在最小生成樹上。可以離線做。刪邊不好做。看成倒序加邊。先維護乙個最小生成樹。每次加邊的時候 看這個邊是否小於最小生成樹中a b路徑的最長邊 一定是這樣!然後保證新新增的邊是有用邊 不會成環的 小於的話,將那個邊刪了,新增這條邊。怎麼記錄答案呢。把邊當成乙個帶...