题目描述

Farmer John 要把他的牛奶运输到各个销售点。运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点。 运输的总距离越小,运输的成本也就越低。低成本的运输是 Farmer John 所希望的。不过,他并不想让他的竞争对手知道他具体的运输方案,所以他希望采用费用第二小的运输方案而不是最小的。现在请你帮忙找到该运输方案。

输入格式

第一行是两个整数 N,MN,MN,M,表示顶点数和边数;

接下来 MMM 行每行 333 个整数,x,y,zx,y,zx,y,z,表示一条路的两端 x,yx,yx,y 和距离 zzz。

输出格式

仅一行,输出第二小方案。

样例

样例输入

4 4
1 2 100
2 4 200
2 3 250
3 4 100

样例输出

450

数据范围与提示

对于全部数据,1≤N≤500,1≤M≤104,1≤z≤1091\le N\le 500,1\le M\le 10^4,1\le z\le 10^91≤N≤500,1≤M≤10​4​​,1≤z≤10​9​​,数据可能有重边。

题解

这是一道裸的次小生成树。

次小生成树的两种食用方法:

  • 就叫它法一吧。

    • 首先求个最小生成树。
    • 然后每次删掉一条树边,求树边两端两点的最短路。
    • 时间复杂度$O(nmlogm)$
  • 就叫它法二吧。
    • 也是首先求个最小生成树。
    • 之后求树上每两点的路径间最大的边权,需要$O(n^2)$。(枚举每个点做根,然后$O(n)$遍历
    • 然后枚举每个非树边,设端点为$i,j$。
    • 那么如果把这条边接上生成树,那么就把它所在的环上边权最大的那条边断掉,就是接上这条边的最优解。
    • 所以枚举每条边,维护$最小生成树的权值和-MAX[i][j]+a[i][j]$的最小值。
    • 复杂度$O(n^2+m)$

然后这里写的是法二。

 编号    题目    状态    分数    总时间    内存    代码 / 答案文件    提交者    提交时间
# #. 「一本通 3.1 练习 」秘密的牛奶运输 Accepted ms KiB C++ / 1.3 K qwerta -- ::
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
struct emm{
int l,r,v,tag;
}a[];
bool cmp(emm qaq,emm qwq){
return qaq.v<qwq.v;
}
int fa[];
int fifa(int x)
{
if(fa[x]==x)return x;
return fa[x]=fifa(fa[x]);
}
struct ahh{
int e,f,v;
}b[];
int h[];
int cnt=;
void con(int x,int y,int len)//加边
{
b[++cnt].f=h[x];
h[x]=cnt;
b[cnt].e=y;
b[cnt].v=len;
b[++cnt].f=h[y];
h[y]=cnt;
b[cnt].e=x;
b[cnt].v=len;
return;
}
int MAX[][];//两点树上路径中边权最大值
int s;
void dfs(int x)//dfs找MAX[s][x]
{
for(int i=h[x];i;i=b[i].f)
if(!MAX[s][b[i].e]&&b[i].e!=s)
{
MAX[s][b[i].e]=max(MAX[s][x],b[i].v);
dfs(b[i].e);
}
return;
}
int main()
{
//freopen("a.in","r",stdin);
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;++i)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
a[i]=(emm){x,y,z};//建原图
}
//跑最小生成树
for(int i=;i<=n;++i)
fa[i]=i;
sort(a+,a+m+,cmp);
int k=n-,i=;
long long now=;//记录最小生成树的边权和
while(k)
{
++i;
int u=fifa(a[i].l),v=fifa(a[i].r);
if(u!=v)
{
fa[u]=v;
con(a[i].l,a[i].r,a[i].v);//建树图
k--;
now+=a[i].v;
a[i].tag=;//标记为树边
}
}
for(s=;s<=n;++s)
{
dfs(s);
}
long long ans=1e15;
for(int i=;i<=m;++i)
if(!a[i].tag&&a[i].v>MAX[a[i].l][a[i].r])//如果该边为非树边并且它的权值大于左右端点的树上距离(因为是次小生成树,所以权值要比最小生成树大
{
ans=min(ans,now-MAX[a[i].l][a[i].r]+a[i].v);//把路径上最大的换成这条边的答案
}
cout<<ans;
return ;
}

题目描述

Farmer John 要把他的牛奶运输到各个销售点。运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点。 运输的总距离越小,运输的成本也就越低。低成本的运输是 Farmer John 所希望的。不过,他并不想让他的竞争对手知道他具体的运输方案,所以他希望采用费用第二小的运输方案而不是最小的。现在请你帮忙找到该运输方案。

输入格式

第一行是两个整数 N,MN,MN,M,表示顶点数和边数;

接下来 MMM 行每行 333 个整数,x,y,zx,y,zx,y,z,表示一条路的两端 x,yx,yx,y 和距离 zzz。

输出格式

仅一行,输出第二小方案。

样例

样例输入

4 4
1 2 100
2 4 200
2 3 250
3 4 100

样例输出

450

数据范围与提示

对于全部数据,1≤N≤500,1≤M≤104,1≤z≤1091\le N\le 500,1\le M\le 10^4,1\le z\le 10^91≤N≤500,1≤M≤10​4​​,1≤z≤10​9​​,数据可能有重边。

最新文章

  1. Web APi之HttpClient注意事项以及建议(四)
  2. C#对SQL Server数据库的备份与还原
  3. Github注册过程
  4. 【ASP.NET Identity系列教程(二)】运用ASP.NET Identity
  5. iOS定位到崩溃代码行数
  6. 欧拉函数 cojs 2181. 打表
  7. 大数据hadoop入门学习之集群环境搭建集合
  8. springMVC导入excel案例poi
  9. hadoop2.2原理:分析HDFS的文件读写
  10. Handler Looper 原理 详解
  11. UVALive 6869(后缀数组)
  12. DSR on Openstack POC
  13. Java7中的ForkJoin并发框架初探(上)——需求背景和设计原理
  14. 学习总结:工程管理与makefile
  15. SourceTree安装跳过注册
  16. node配置微信小程序解密消息以及推送消息
  17. 自编译Apache Spark2.3.3支持CDH5.16.1
  18. .net Framework 源代码 &#183; ScrollViewer
  19. 《DSP using MATLAB》Problem 5.8
  20. September 26th 2017 Week 39th Tuesday

热门文章

  1. mysql 让一个存储过程定时作业的代码(转)
  2. JavaScript读书笔记(6)-Array RegExp
  3. centOS中如何修改运行级别!
  4. MySQL数据库的常见操作(七)
  5. iOS 键盘变中文
  6. pycharm连git和gitee
  7. 【BZOJ1835】[ZJOI2010]base 基站选址 线段树+DP
  8. android菜鸟学习笔记1----环境搭建
  9. wepy项目中使用async await
  10. CSS浏览器兼容性问题解决方法总结