題意:問圖上任意兩點(u,v)之間的路徑上,所經過的最大邊權最小為多少?
求最小瓶頸路,既是求最小生成樹。因為要處理多組詢問,所以需要用倍增加速。
先處理出最小生成樹,prim的時間複雜度為o(n*n),kruskal為o(mlogm)。前者適合處理稠密圖,後者適合處理稀疏圖。
這裡的倍增處理是值得記住的,在樹上做多組詢問;亦或是,將無向圖縮點在詢問,都是可以這樣加速的。
注意:邊權<=1e9
1 #include2 #include3 #include4 #include5 #include6view code#define clr(a,m) memset(a,m,sizeof(a))
7#define rep(i,a,b) for(int i=a;i<=b;i++)
8using
namespace
std;910
const
int maxn=55555;11
const
int inf=1e9;
12const
int pow =18;13
14struct
edge
19};
2021 priority_queueq;
22 vectorg[maxn];
23 vectoredge;
2425
intfa[maxn];
2627
intp[maxn][pow],max[maxn][pow],d[maxn];
2829
void init(int
n)30
3839
void add(int u,int v,int
c)40
);42
int m=edge.size();
43 g[u].push_back(m-1
);44}45
46int find(int
x)47
5051
void kruskal(int
n)5267}
68}6970
void dfs(int u,int fa,int
c)71
80int sz=g[u].size();
81 rep(i,0,sz-1)87
}8889int lca( int a, int
b )90
100}
101if( a !=b )
109 ans=max(ans,max[a][0
]);110 ans=max(ans,max[b][0
]);111 a = p[a][0
];112 b = p[b][0
];113
}114
return
ans;
115}
116117
void lca(int
n)118
129}
130131
intmain()
132);
142}
143kruskal(n);
144lca(n);
145}
146return0;
147}
148/*
1499 8
1501 2 10
1511 3 20
1522 4 20
1532 5 30
1543 6 30
1553 7 10
1564 8 30
1575 9 10
15836
1591 2
1601 3
1611 4
1621 5
1631 6
1641 7
1651 8
1661 9
1672 3
1682 4
1692 5
1702 6
1712 7
1722 8
1732 9
1743 4
1753 5
1763 6
1773 7
1783 8
1793 9
1804 5
1814 6
1824 7
1834 8
1844 9
1855 6
1865 7
1875 8
1885 9
1896 7
1906 8
1916 9
1927 8
1937 9
1948 9
195*/
UVA11354 Bond 並查集按秩合併
給定乙個 n 個頂點 m 條邊的帶權無向圖,多次詢問在兩個點之間所有可能的路徑中的最大值,最小為多少。顯然,可以先在用 kruskal 演算法在原圖上構造一棵最小生成樹。可以證明,兩點之間的路徑在這棵樹上時,邊權的最大值最小。而對於找到這個最大值有兩種做法,一種是在求最近公共祖先時記錄下路徑上的最大...
UVa 11354 邦德(最小瓶頸路 LCA)
題意 有n個城市m條道路,每條道路有乙個危險係數。先在有若干個詢問,要求找到一條從s到t的路,使得途徑所有邊的最大危險係數最小。思路 最小瓶頸路肯定是在最小生成樹上的。所有先求最小生成樹。然後將它轉化成有根樹,讓fa i 和cost i 分別表示結點i的父親編號和它與父親之間的邊權l i 表示結點i...
UVA 11354 LCA 最小生成樹
點選開啟鏈結 題意 給乙個無向圖,然後有q次詢問u v,問的是u到v的所有路徑中的最小值最大 思路 u到v的路徑最小值最大,則這條邊肯定是最小生成樹上的邊,那麼我們可以先將所有的最小生成樹上的邊全都找出來,然後現在是乙個樹,然後跑一邊lca,對於現在詢問的u到v,只要找到它們的最近公共祖先,然後兩個...