題意:有n個城市m條道路,每條道路有乙個危險係數。先在有若干個詢問,要求找到一條從s到t的路,使得途徑所有邊的最大危險係數最小。
思路:最小瓶頸路肯定是在最小生成樹上的。所有先求最小生成樹。
然後將它轉化成有根樹,讓fa[i]和cost[i]分別表示結點i的父親編號和它與父親之間的邊權l[i]表示結點i的深度。
anc[i][j]表示結點i的第2^j級祖先的編號(j==0時候就是fa[i],如果第2^j祖先不存在,設為-1)。
maxcost[i][j]表示結點i和第2^j級祖先之間路徑上的最大權值。
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10
using
namespace
std;
11 typedef long
long
ll;12
const
int maxn=50000+5;13
const
int inf=0x3f3f3f;14
15struct
node
1622 }edge[2*maxn];
2324
intn,m;
25int
cnt;
26int
p[maxn];
27 vectorg[maxn];
28 vectorc[maxn];
2930
int find(int
x)31
3435
struct
lca36
51for(int j=1;(1
<)
5260}61
}6263int query(int p,int
q)64
7677
if(p==q) return ans; //
lca為p
7879
for(int i=log;i>=0;i--)
80if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i])//
否則,讓p,q同時往上爬,保證爬的時候始終處於同一層
8185 ans=max(ans,cost[p]);
86 ans=max(ans,cost[q]);
87return ans; //
lca為fa[p](或fa[q])88}
89}solver;
9091
void
mst()
92106
}107
}108
109void dfs(int u,int fa,int level) //
無根樹轉有根樹
110121
}122
}123
124int
main()
125132
for(int i=0;i)
133141
mst();
142 dfs(0,-1,0
);143 solver.n=n;
144solver.preprocess();
145int
q;146
if(kase++!=1) puts(""
);147 scanf("
%d",&q);
148while(q--)
149154
}155
return0;
156 }
UVA 11354 Bond(最小瓶頸路 倍增)
題意 問圖上任意兩點 u,v 之間的路徑上,所經過的最大邊權最小為多少?求最小瓶頸路,既是求最小生成樹。因為要處理多組詢問,所以需要用倍增加速。先處理出最小生成樹,prim的時間複雜度為o n n kruskal為o mlogm 前者適合處理稠密圖,後者適合處理稀疏圖。這裡的倍增處理是值得記住的,在...
最小瓶頸路
題目 uva 534 題目大意 有兩隻青蛙,在兩塊不同的石頭上,有乙隻想要去拜訪另乙隻,要求通過它石頭進行跳躍然後在一起呀在一起,可想而知,由於石頭有很多,他們中間的路徑也有很多,現在要求求乙個長度 從每條路徑裡面挑出那步跨越最大的,然後從這些跨越最大的裡面挑出最小的。分析 flody 的改版 in...
最小瓶頸路
在一張無向圖中,詢問乙個點對 u,v 找出從u到v的一條簡單路徑,使路徑上所有邊中最大值最小。應用 次小生成樹 給定一張無向圖,求出一棵生成樹,其所有邊的權值之和僅次於最小生成樹的權值之和 如果有多個最小生成樹的話次小生成樹就是最小生成樹 思路 先求出最小生成樹。列舉所有樹外的邊加入最小生成樹,則一...