給乙個n個點m條邊(n <= 100000, m <= 300000) 的無向圖,求它的嚴格次小生成樹。
資料範圍很大,o(n^2)的演算法顯然是不行的。由於最小生成樹是一棵樹,求任意兩點路徑上的最大/次大邊就成為了經典的lca問題。因此,我們得到了下面的演算法:1、把邊按權值從小到大排序,時間複雜度為o(mlogm);2、用kruskal演算法求出原圖的最小生成樹(利用並查集),時間複雜度為o(mα(n));3、以最小生成樹的任意一點為根,用倍增法預處理出最小生成樹上每個點往上第2^k層的祖先和到往上第2^k層的祖先路徑上的最大邊和次大邊,時間複雜度為o(nlogn)(該過程必須bfs實現,因為dfs會爆棧);4、窮舉每一條非最小生成樹上的邊(u, v),用這條邊替換從u到v路徑上的最大邊(p, q),由於要嚴格次小,如果w(u, v) = w(p, q),則替換從u到v路徑上的次大邊(p', q'),對所有這樣形成的新生成樹取權值和最小的即為要求的嚴格次小生成樹(從u到v路徑上的最大/次大邊利用倍增法求lca的過程實現),時間複雜度為o(mlogn)。因此,由於n一般小於m,演算法總體時間複雜度仍為o(mlogm)。
**(由於一開始沒有用long long,2y)
#include
#include
#include
#include
using namespace std;
#define f1 first
#define f2 second
typedef long long ll;
typedef pairpii;
const int maxn = 100001, maxm = 300000;
struct edge
e[maxm];
struct adj_list
a[maxn << 1];
struct set
s[maxn];
bool v[maxn], in[maxm];
int n, m, size, h[maxn], log2[maxn],
fa[maxn][20], dep[maxn], q[maxn];
ll mst;
pii d[maxn][20];
inline bool operator < (edge x, edge y)
inline void make_set(int x)
int find_set(int x)
inline void union_set(int x, int y)
else
}inline void add_edge(int x, int y, int w)
inline void check_max(int &x, int y)
inline void check_min(ll &x, ll y)
inline int getint()
inline void init()
sort(e, e + m);
for (int i = 1, j = 0; i <= n; ++ i)
}inline void kruskal()}}
inline void bfs()
for (int k = h[u]; k != -1; k = a[k].nxt)
if (!v[a[k].v])}}
inline pii max_edge(int x, int y)
if (x == y)
return ret;
for (int k = log2[dep[x]]; k >= 0; -- k)
if (fa[x][k] != fa[y][k])
check_max(ret.f1, max(d[x][0].f1, d[y][0].f1));
check_max(ret.f2, max(d[x][0].f1 != ret.f1 ? d[x][0].f1 : d[x][0].f2,
d[y][0].f1 != ret.f1 ? d[y][0].f1 : d[y][0].f2));
return ret;
}inline void work()
printf("%lld\n", ans);
}int main()
次小生成樹(倍增 lca)
題目描述給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。輸入格式 第一行包含兩個整數n和m。接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊的權值為z。輸出格式 包含一...
次小生成樹(最小生成樹演算法 倍增LCA)
次小生成樹 顯然就是除開最小生成樹外最小的乙個生成樹。非嚴格次小生成樹 權值和 最小生成樹。嚴格次小生成樹 權值和 最小生成樹 求解 每次在非最小生成樹的邊裡找一條,將這條邊加入樹,此時一定形成環,再刪去環中除該邊外最大的一條邊。依次列舉每條邊,找到加入邊 刪除邊最小的一種情況,即可求出非嚴格次小生...
lca 次小生成樹
倍增法求lca 求小資料次小生成樹 給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。輸入格式 第一行包含兩個整數n和m。接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊...