給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。
設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。
第一行包含兩個整數n和m。
接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊的權值為z。
包含一行,僅乙個數,表示嚴格次小生成樹的邊權和。(資料保證必定存在嚴格次小生成樹)
n≤105,m≤3∗105
lca次小生成樹。倍增找樹上路徑最大邊即可。
#include
using
namespace std;
typedef
long
long ll;
typedef pair<
int,
int> pii;
typedef
unsigned
long
long ull;
const
int n=
100010
,m=300010
,inf=
0x3f3f3f3f
;int n,m;
struct edge
}edge[m]
;int p[n]
;int h[n]
,e[m]
,w[m]
,ne[m]
,idx;
int depth[n]
,fa[n][17
],d1[n][17
],d2[n][17
];int q[n]
;void
add(
int a,
int b,
int c)
intfind
(int x)
ll kruskal()
}return res;
}void
build()
}void
bfs();
d1[j]
[k]=d2[j]
[k]=
-inf;
for(
int u=
0;u<
4;u++)}
}}}}
intlca
(int a,
int b,
int w)}if
(a!=b)
} distance[cnt++
]=d1[a][0
];distance[cnt++
]=d1[b][0
];}int dist1=
-inf,dist2=
-inf;
for(
int i=
0;i(w>dist1)
return w-dist1;
if(w>dist2)
return w-dist2;
return inf;
}int
main()
;}ll sum=
kruskal()
;build()
;bfs()
; ll res=
1e18
;for
(int i=
0;icout
}
AcWing 356 次小生成樹
一道蠻經典的題目,隨手記錄下。題目描述 給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。注意本題所求的次小生成樹是嚴格次小的 題解 先用kruskal求出給定圖的最小生成樹,再列舉沒有被選上的...
AcWing 356 次小生成樹
題目 給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。嚴格次小生成樹 設最小生成樹的邊權之和為 mathrm 嚴格次小生成樹就是指邊權之和大於 mathrm 的生成樹中最小的乙個。輸入格式 第一行包含兩個整數 n 和 m 接下來 m 行,每行包含三個整數 x,y,z 表示點 x 和點...
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...