題目大意:
在乙個「無向有色圖」中求一棵最小生成樹,且要求樹邊必須包含至少兩種顏色。 1≤
n點數,
e邊數≤
100000,1
≤col
or顏色
,w邊數
≤1000000000
1 ≤n
點數,e
邊數
≤100000,1
≤col
or顏色
,w邊數
≤1000000000
第一眼看到資料範圍簡直令人絕望
不過,據大佬說這題只是noip普及組難度!!!關鍵是考試時居然寫炸了!!!
但實際上很多時候這些巨大數值並無關緊要:hash,離散等,只要麻煩點預處理一下就ok了
當然,對於這題是不需要的
思考一下,顯然先求他一趟最小生成樹——
若此時顏色已經滿足,那最好,直接出了答案
但若不滿足呢?顯然也是在這棵最小生成樹上做一些變動來得到答案
那麼關鍵就是如何變動了
——事實上,有且僅有一條原樹邊會被替換掉:
首先,顯然,替換了一條樹邊後樹邊的總權值變大了(不然原來的就不叫最小生成樹了)
那麼假如我們再替換一條邊,樹邊的總權值還會變大
所以說,有且僅有一條原樹邊會被替換掉
然後,這不就是變形的次小生成樹嗎?
加入一條邊後,在這條邊所形成的環中找一條最大的樹邊替換掉
快速找樹上最大邊——lca另開個p陣列記一下權值不就ok了嗎?
於是:
kruskal+建最小生成樹
lca+預處理p陣列
列舉一條顏色不同的邊「假裝」加入,求此時次小生成樹
#include
#include
#define ll long long
#define max(x,y) max(x,y)
#define min(x,y) (x)<(y)?(x):(y)
using
namespace
std;
const
int maxn=(1e5)+5,log=21;
int n,m,col=-1,fa[maxn];bool vis[maxn],***=0;ll ans,val=((ll)1
<<60);
int getfa(int x)
int tot,son[maxn<<1],nxt[maxn<<1],lnk[maxn],w[maxn<<1];
void add_e(int x,int y,int z)
int dep[maxn],up[maxn][log],p[maxn][log],pow[maxn];
void dfs(int x,int da,int va)
int lca(int x,int y)
struct ff
}char gt()
int read()
int main();
work();
if(***)
dfs(1,0,0);
for(int i=1;i<=n;i++) pow[i]=pow[i-1]+((1
printf("%lld\n",val);
return
0;}
題解 SHOI2010 最小生成樹
題目大意 在乙個合法的連通圖中,每條邊都有乙個邊權,我們欽定一條邊。然後對圖進行一些操作 將某一條邊的權值 1或 1。請問至少多少次後可以使欽定的邊出現在該圖的最小生成樹中。luogu傳送門 shoi2010 最小生成樹 解題思路 說實話 我們一定要跳出題目的侷限性,畢竟網路流是屬於圖演算法。我們考...
貨車運輸題解 最大生成樹 lca
2013年noip全國聯賽提高組 時間限制 1 s 空間限制 128000 kb a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入描述 in...
BZOJ1016 最小生成樹計數 題解
顯然的是,不同的生成樹的不同權值的邊數一定是一樣的 我們可以先跑一遍kruskal把每種邊需要多少條記錄一下 然後由於相同權值的邊不超過10條,所以在相同權值的邊內部搜一下,看哪些邊加進原圖無環 然後乘法原理和前面的答案乘一下 不同的選擇方法對後面的並查集的更新肯定是沒有影響的,不然一開始的krus...