農夫約翰要把他的牛奶運輸到各個銷售點。
運輸過程中,可以先把牛奶運輸到一些銷售點,再由這些銷售點分別運輸到其他銷售點。
運輸的總距離越小,運輸的成本也就越低。
低成本的運輸是農夫約翰所希望的。
不過,他並不想讓他的競爭對手知道他具體的運輸方案,所以他希望採用費用第二小的運輸方案而不是最小的。
現在請你幫忙找到該運輸方案。
注意::
如果兩個方案至少有一條邊不同,則我們認為是不同方案;
費用第二小的方案在數值上一定要嚴格小於費用最小的方案;
答案保證一定有解;
輸入格式
第一行是兩個整數 n,m,表示銷售點數和交通線路數;
輸出格式
輸出費用第二小的運輸方案的運輸總距離。
資料範圍
1≤n≤500,
1≤m≤104,
1≤z≤109,
資料中可能包含重邊。
輸入樣例:
4 41 2 100
2 4 200
2 3 250
3 4 100
輸出樣例:
450定理:對於一張無向圖,如果存在最小生成樹和(嚴格)次小生成樹,對於任何一顆最小生成樹,都存在一顆(嚴格)次小生成樹,使得這兩顆樹只有一條邊不同。
最小生成樹有兩種方法求,我這裡是用的先求出最小生成樹,然後列舉每個點對之間的最大的邊和次大的邊。然後用嚴格大於他們的非樹上的邊進行替換得到的。(定理:次小生成樹一定存在於最小生成樹中的最大或次大被非樹上的邊替換的領集中)。
易錯:注意在求嚴格次小生成樹時,不能只預處理兩點之間最大的樹邊,因為當最大樹邊和當前列舉的非樹邊長度相同時,就不能替換了,但此時卻可以替換長度次大的樹邊。因此還需同時預處理出長度次大的樹邊。
#include
#define int long long
using
namespace std;
const
int n=
1e5+7;
int n,m;
int ne[n]
,head[n]
,e[n]
,w[n]
,cnt,dis1[
505]
[505
],dis2[
505]
[505
],pre[n]
,sum;
struct node
}node[n]
;void
add(
int a,
int b,
int c)
intfind
(int x)
void
kru()}
}void
dfs(
int u,
int f,
int maxd1,
int maxd2,
int d1,
int d2)
}signed
main()
sort
(node,node+m)
; sum=0;
kru();
for(
int i=
1;i<=n;i++
)dfs
(i,-1,
0,0,dis1[i]
,dis2[i]);
int res=
1e18
;for
(int i=
0;i)else
if(c>dis2[a]
[b])}}
cout
}
次小生成樹 秘密的牛奶運輸
農夫約翰要把他的牛奶運輸到各個銷售點。運輸過程中,可以先把牛奶運輸到一些銷售點,再由這些銷售點分別運輸到其他銷售點。運輸的總距離越小,運輸的成本也就越低。低成本的運輸是農夫約翰所希望的。不過,他並不想讓他的競爭對手知道他具體的運輸方案,所以他希望採用費用第二小的運輸方案而不是最小的。現在請你幫忙找到...
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...
次小生成樹
演算法引入 設g v,e,w 是連通的無向圖,t是圖g的一棵最小生成樹 如果有另一棵樹t1,滿足不存在樹t t t1 則稱t1是圖g的次小生成樹 演算法思想 鄰集的概念 由t進行一次可行交換得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n t 設t是圖g的最小生成樹,如果t1滿足 t1 min,...