源自大白書
題意 有n座城市通過m條雙向道路相連,每條道路都有乙個危險係數。你的任務是回答若干個詢問,每個詢問包含乙個起點s和乙個終點t,要求找到一條從s到t的路,使得途徑所有的邊的大最大危險係數最小。
解: 首先求出最小生成樹,並把它改寫成有根樹,讓fa[i]和cost[i]分別表示節點i的父親編號和它與父親之間的邊權,l[i]表示節點i的深度,接下來通過預處理計算出陣列anc 和 maxcost 其中anc[i][j] 表示節點i的2^j 級祖先的編號 macost[i][j] 表示i到2^j級 祖先之間的最大權值。
有了預處理 私用lca 來查詢結果, 查詢p,q, 並且p比q深, 則可以先把p提公升到和q處於同一級的位置,然後用二進位制展開的方法不斷把p和q同時往上提(保證二者深度相等),同時更新最大的邊權
1 #include 2 #include 3 #include 4 #include5 #include 6
using
namespace
std;
7const
int maxn = 50000+10;8
const
int inf =2000000000;9
struct
edge
14 }e[maxn*2
];15
struct
ed;18 vectorg[maxn];
19int
fa[maxn],per[maxn],cost[maxn],l[maxn];
20int anc[maxn][20],maxcost[maxn][20
];21
void inti(int
n)26}27
void preprocess( int
n)32
for(int j =1; (1
<)
33for(int i=0; i)39}
40}41int fid(int
u)44
void dfs(int u, int p,int dist, int
depth)51}
52int query(int p, int
q)62
if(p==q) return
ans;
63for(int i=log; i>=0; i--)
64if(anc[p][i]!=-1 && anc[p][i]!=anc[q][i])
68 ans =max(ans,cost[p]);
69 ans =max(ans,cost[q]);
70return
ans;71}
72int
main()73;
82}83int lest =n;
84 sort(e,e+m);
85for(int i=0; i) );
92g[b].push_back((ed) );
93if(lest==1) break;94
}95}96 dfs(0,-1,0,0
);97
preprocess(n);
98int
q;99
if(f)
100 puts(""
);101
else f=1
;102 scanf("
%d",&q);
103for(int i =0; i)
109110
}111
112return0;
113 }
UVA 11354 LCA 最小生成樹
點選開啟鏈結 題意 給乙個無向圖,然後有q次詢問u v,問的是u到v的所有路徑中的最小值最大 思路 u到v的路徑最小值最大,則這條邊肯定是最小生成樹上的邊,那麼我們可以先將所有的最小生成樹上的邊全都找出來,然後現在是乙個樹,然後跑一邊lca,對於現在詢問的u到v,只要找到它們的最近公共祖先,然後兩個...
UVa 11354 邦德(最小瓶頸路 LCA)
題意 有n個城市m條道路,每條道路有乙個危險係數。先在有若干個詢問,要求找到一條從s到t的路,使得途徑所有邊的最大危險係數最小。思路 最小瓶頸路肯定是在最小生成樹上的。所有先求最小生成樹。然後將它轉化成有根樹,讓fa i 和cost i 分別表示結點i的父親編號和它與父親之間的邊權l i 表示結點i...
次小生成樹(最小生成樹演算法 倍增LCA)
次小生成樹 顯然就是除開最小生成樹外最小的乙個生成樹。非嚴格次小生成樹 權值和 最小生成樹。嚴格次小生成樹 權值和 最小生成樹 求解 每次在非最小生成樹的邊裡找一條,將這條邊加入樹,此時一定形成環,再刪去環中除該邊外最大的一條邊。依次列舉每條邊,找到加入邊 刪除邊最小的一種情況,即可求出非嚴格次小生...