一道蠻經典的題目,隨手記錄下。
題目描述:
給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。
設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。
注意本題所求的次小生成樹是嚴格次小的
題解:先用kruskal求出給定圖的最小生成樹,再列舉沒有被選上的邊,假設把這條邊加上,就會形成乙個環,只要把環中的最大邊刪去,就可以得到一顆新的樹,列舉後得到最小的新樹就是次小生成樹。這裡注意
因為是嚴格次小所以我們需要判斷每個環中的最大邊是否和新加入的邊一樣,所以還需要維護乙個次大邊。我們用lca倍增來維護就可以使時間複雜度降到nlogn
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#pragma gcc optimize(2)
//#define int long long
#define rush() int t;scanf("%d",&t);for(int ti=1;ti<=t;++ti)
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define pi acos(-1)
#define fi first
#define se second
//你冷靜一點,確認思路再敲!!!
using
namespace
std;
typedef
long
long
ll;typedef pair
pii;
priority_queue
< pii, vector, greater>que;
stringstream ssin;
//ssin << string while ( ssin >> int)
const
int n = 1e5 + 5, m = 6e5 + 5, mod = 1e9 + 7, inf = 0x3f3f3f3f
;int
n, m, t, anc;
inte[m], ne[m], h[m], w[m], idx;
int fa[n][20], d1[n][20], d2[n][20
], depth[n];
intp[n];
inline
intread()
while(c>='
0'&&c<='9')
return x*f;
}void add(int a, int b, int
c) struct
edge
}edge[m];
int find(int
x) ll kruskal()
return
res;
}void
build()
}void
bfs() ;
d1[v][k] = d2[v][k] = -inf;
for (int j = 0; j < 4; ++j)
else
if (dis[j] !=d1[v][k])}}
}}
}}int lca(int a, int b, int
c) }
if (a !=b)
}dd[++cnt] = d1[a][0
]; dd[++cnt] = d1[b][0
]; }
int dis1 = -inf, dis2 = -inf; //
最大和次大
for (int i = 1; i <= cnt; ++i)
else
if (d !=dis1)
}if (c > dis1) return c -dis1;
if (c > dis2) return c -dis2;
return
inf;
}int
main()
; }
ll res =kruskal();
//cout << res << '\n';
build();
bfs();
ll ans =1e18;
for (int i = 1; i <= m; ++i)
cout
<< ans << '\n'
;
//system("pause");
}
AcWing 356 次小生成樹
題目 給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。嚴格次小生成樹 設最小生成樹的邊權之和為 mathrm 嚴格次小生成樹就是指邊權之和大於 mathrm 的生成樹中最小的乙個。輸入格式 第一行包含兩個整數 n 和 m 接下來 m 行,每行包含三個整數 x,y,z 表示點 x 和點...
AcWing 356 次小生成樹(lca)
給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。第一行包含兩個整數n和m。接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊的權值為z。包含一行,僅乙個數,表示嚴格次小生...
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...