秘密的牛奶运输
农夫约翰要把他的牛奶运输到各个销售点。
运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点。
运输的总距离越小,运输的成本也就越低。
低成本的运输是农夫约翰所希望的。
不过,他并不想让他的竞争对手知道他具体的运输方案,所以他希望采用费用第二小的运输方案而不是最小的。
现在请你帮忙找到该运输方案。
注意::
如果两个方案至少有一条边不同,则我们认为是不同方案;
费用第二小的方案在数值上一定要严格小于费用最小的方案;
答案保证一定有解;
输入格式
第一行是两个整数 N,M,表示销售点数和交通线路数;
接下来 M 行每行 3 个整数 x,y,z,表示销售点 x 和销售点 y 之间存在线路,长度为 z。
输出格式
输出费用第二小的运输方案的运输总距离。
数据范围
1≤N≤500,
1≤M≤104,
1≤z≤109,
数据中可能包含重边。
输入样例:
4 4
1 2 100
2 4 200
2 3 250
3 4 100
输出样例:
450
定理:对于一张无向图,如果存在最小生成树和(严格)次小生成树,对于任何一颗最小生成树,都存在一颗(严格)次小生成树,使得这两颗树只有一条边不同。
题解:
最小生成树有两种方法求,我这里是用的先求出最小生成树,然后枚举每个点对之间的最大的边和次大的边。然后用严格大于他们的非树上的边进行替换得到的。(定理:次小生成树一定存在于最小生成树中的最大或次大被非树上的边替换的领集中)。
易错:注意在求严格次小生成树时,不能只预处理两点之间最大的树边,因为当最大树边和当前枚举的非树边长度相同时,就不能替换了,但此时却可以替换长度次大的树边。因此还需同时预处理出长度次大的树边。
#include <bits/stdc++.h>
#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{
int u,v,cost;
bool lef;
bool operator< (const Node &b)const {
return cost<b.cost;
}
}node[N];