時間限制: 1000 ms 記憶體限制: 524288 kb
小 c 最近學了很多最小生成樹的演算法,prim 演算法、kurskal 演算法、消圈演算法等等。 正當小 c 洋洋得意之時,小 p 又來潑小 c 冷水了。小 p 說,讓小 c 求出乙個無向圖的次小生成樹,而且這個次小生成樹還得是嚴格次小的,也就是說: 如果最小生成樹選擇的邊集是 em,嚴格次小生成樹選擇的邊集是 es,那麼需要滿足:(value(e) 表示邊 e的權值) ∑e
∈emv
alue
(e)<∑e
∈esv
alue
(e) ∑e∈
emva
lue(
e)
<∑e
∈esv
alue
(e
)這下小 c 蒙了,他找到了你,希望你幫他解決這個問題。
第一行包含兩個整數
n n
和m' role="presentation" style="position: relative;">m
m,表示無向圖的點數與邊數。 接下來
m m
行,每行 3個數
x' role="presentation" style="position: relative;">xxy
y
z' role="presentation" style="position: relative;">z
z表示,點
x x
和點y' role="presentation" style="position: relative;">y
y之間有一條邊,邊的權值為
z z
。包含一行,僅乙個數,表示嚴格次小生成樹的邊權和。(資料保證必定存在嚴格次小生成樹)
輸入樣例
5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6
輸出樣例11
資料中無向圖無自環;
50% 的資料n≤
2000,m
≤3000' role="presentation" style="position: relative;">n≤2
000,m≤
3000n≤
2000,m
≤3000;
80% 的資料n≤
50000,m
≤100
000 n≤50
000,m≤
100000
; 100% 的資料n≤
100000,m
≤300
000 n
≤100
000,m≤
300000
,邊權值非負且不超過 109109
。' role="presentation" style="position: relative;">
' role="presentation" style="position: relative;">
' role="presentation" style="position: relative;">
' role="presentation" style="position: relative;">
' role="presentation" style="position: relative;">
次小生成樹的一般解法?
先建立最小生成樹,列舉加入非樹邊,求環上最大值,然後減去這條邊就是答案。由於我們不知道環上的最值是否和非樹邊相等,所以我們還需要維護乙個次大值。
其實演算法很好理解,這裡有乙個問題,筆者似乎無法解答。次大生成樹似乎不滿足kruskal的貪心性質?假如我們把非樹邊排序,加入最小邊不一定是次小生成樹。希望有人可以解答。
估計是我kruskal太菜了。
關於**實現:維護次大值似乎沒有什麼好的方法,寫得很麻煩。然後好久沒有倍增了,倍增求還要特判
u u
,v' role="presentation" style="position: relative;">v
v是不是lc
a lca
。code:
#include
#include
#include
#include
using
namespace
std;
struct lxyeg[600005];
struct data
}yyy;
int n,m,t,cnt=-1,head[100005],dep[100005];
long
long ans,rans=0x7f7f7f7f7f7f7f7f;
int f[100005][18],s[100005][18],fa[100005][18];
bool vis[100005];
void add(int op,int ed,int len)
void prim()
while(!d.empty()&&vis[d.top().id]==1) d.pop();
}}void woc(int x,int y,int p)
if(p==fi&&si!=-1) rans=min(rans,ans+p-si);
else
if(p!=fi) rans=min(rans,ans+p-fi);
}int main()
prim();
for(int i=1;i<=17;i++)
for(int j=1;j<=n;j++)
for(int i=1;i<=n;i++)
for(int j=head[i];j!=-1;j=eg[j].next)
printf("%lld",rans);
}
次小生成樹Tree
小c最近學了很多最小生成樹的演算法,prim演算法 kurskal演算法 消圈演算法等等。正當小c洋洋得意之時,小p又來潑小c冷水了。小p說,讓小c求出乙個無向圖的次小生成樹,而且這個次小生成樹還得是嚴格次小的,也就是說 如果最小生成樹選擇的邊集是em,嚴格次小生成樹選擇的邊集是es,那麼需要滿足 ...
次小生成樹 倍增 LCA
給乙個n個點m條邊 n 100000,m 300000 的無向圖,求它的嚴格次小生成樹。資料範圍很大,o n 2 的演算法顯然是不行的。由於最小生成樹是一棵樹,求任意兩點路徑上的最大 次大邊就成為了經典的lca問題。因此,我們得到了下面的演算法 1 把邊按權值從小到大排序,時間複雜度為o mlogm...
次小生成樹(倍增 lca)
題目描述給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。輸入格式 第一行包含兩個整數n和m。接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊的權值為z。輸出格式 包含一...