题目描述:

有一天,pqq准备去给×i×准备礼物,他有一些礼品准备包装一下,他用线将这些礼物连在一起,不同的礼物因为风格不同所以连接它们需要不同价值的线。风格差异越大,价格越大(所以两个礼物之间只有一种连接价格),当然有些礼物实在太不友好,所以有些礼物无法相连。pqq打算把所有礼物打包在一起,他不准备花太多钱,但更不想花最少的钱(免得被拒绝)。所以他想知道第二便宜的包装方案(可重复,pqq会认为这是天命并直接选用最小代价来包装礼物),同时,他还想知道最小的包装代价以向×i×进行炫耀。但是由于pqq不够心灵手巧,所以他准备找你来帮他计算答案。

 

输入格式:

 两个数n,m表示有n个礼物,有m对礼物可以相连1≤n,m≤2∗105

 接下来的m行每行三个数a,b,c,表示a礼物和b礼物可以用c的价值相连 , 1≤a,b≤n,1≤c≤106

 

输出格式:

输出一行,包含两个数,分别是最小代价和次小代价

 

样例输入:

5 10
1 2 1
2 3 2
3 4 3
4 5 4
1 3 5
1 4 6
1 5 7
2 4 8
2 5 9
3 5 10

 

样例输出:

10 11

瞎扯:我其实很好奇XiX是谁啊┐(´∀`)┌

题解:其实非严格次小生成树的思路还是很好理解的
首先是什么是非严格次小生成树
就是树边和可以等于和大于最小生成树的另一颗生成树
假设现在要把一条非树边(u,v,c)加入最小生成树,想必要去掉一条原生成树中u->v的边,显然去掉最大边效果是最好的
所以在最小生成树上跑一个倍增DP,d[i][j]表示j的2^i次祖先到j的路径中最大的值
显然可以跟跳lca一样的在logn的跳出u->v路径上的最大值,当然树链剖分也是可以搞这个东西的,但是再写一颗线段树还享受lognlogn的复杂度
emmmm,何必呢……
如果能跳出这个值,我们只要枚举每一条非树边,就可以在nlogn的复杂度里跳出非严格次小生成树,然后就A掉了 代码如下:
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pii pair<int,int>
#define mp make_pair
#define int long long
using namespace std; int fa[],vis[],deep[],n,m,f[][],d[][],ans1,ans2;
vector<pii> g[];
struct line
{
int from,to,cost;
}l[]; int cmp(line a,line b)
{
return a.cost<b.cost;
} void init()
{
for(int i=;i<=n;i++)
{
fa[i]=i;
}
} int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
} void unity(int t,int x,int y,int c)
{
int fx=find(x);
int fy=find(y);
if(fx==fy) return ;
fa[fx]=fy;
ans1+=c;
vis[t]=;
g[x].push_back(mp(y,c));
g[y].push_back(mp(x,c));
} void dfs(int now,int ff,int dist,int dep)
{
d[][now]=dist;
f[][now]=ff;
deep[now]=dep;
for(int i=;i<=;i++)
{
f[i][now]=f[i-][f[i-][now]];
}
for(int i=;i<=;i++)
{
d[i][now]=max(d[i-][now],d[i-][f[i-][now]]);
}
for(int i=;i<g[now].size();i++)
{
if(g[now][i].first==ff) continue;
dfs(g[now][i].first,now,g[now][i].second,dep+);
}
} int get(int u,int v)
{
int x=u,y=v;
if(deep[x]<deep[y]) swap(x,y);
int di=;
for(int i=;i>=;i--)
{
if(deep[f[i][x]]>=deep[y])
{
di=max(di,d[i][x]);
x=f[i][x];
}
}
if(x==y) return di;
for(int i=;i>=;i--)
{
if(f[i][x]!=f[i][y])
{
di=max(max(d[i][x],d[i][y]),di);
x=f[i][x];
y=f[i][y];
}
}
return max(di,max(d[][x],d[][y]));
} signed main()
{
scanf("%lld%lld",&n,&m);
init();
for(int i=;i<=m;i++)
{
scanf("%lld%lld%lld",&l[i].from,&l[i].to,&l[i].cost);
}
sort(l+,l+m+,cmp);
for(int i=;i<=m;i++)
{
unity(i,l[i].from,l[i].to,l[i].cost);
}
dfs(,,,);
ans2=1e16;
for(int i=;i<=m;i++)
{
if(!vis[i])
{
ans2=min(ans2,ans1+l[i].cost-get(l[i].from,l[i].to));
}
}
printf("%lld %lld\n",ans1,ans2);
}

 

最新文章

  1. JavaScript系列文章:从let和const谈起
  2. python 中*args 和 **kwargs
  3. 对象Clone
  4. 九校联考 终&amp;启
  5. 博客的开端,找对象不再new
  6. OpenStack学习系列-----第二篇 由一个错误看理解整个架构的重要性
  7. poj2000---和1969一样的模板
  8. 通过钩子程序跨程序关闭Window
  9. springMVC使用HandlerMethodArgumentResolver 自定义解析器实现请求参数绑定方法参数
  10. mongoDB 数据库简介
  11. 北京AI外包团队 祝大家2019事业有事,大吉大利!
  12. Android中自定义Preference
  13. 内容分享-迅为IMX6开发板编译问题及解决方法
  14. oracle安装教程
  15. Win10系统无法使用小米手机的远程管理功能
  16. iris数据集(.csv .txt)免费下载
  17. 分布式全局ID生成器设计
  18. MySql折腾小记二:text/blog类型不允许设置默认值,不允许存在两个CURRENT_TIMESTAMP
  19. 【selenium】selenium ide的安装过程
  20. Ubuntu系统Apache Maven安装

热门文章

  1. msyqld 的 The user specified as a definer (&#39;root&#39;@&#39;%&#39;) does not exist 问题
  2. OD 实验(三) - 破解程序的文件验证
  3. Python极其简单的分布式异步作业管理系统RQ入门
  4. Protobuf3教程
  5. 使用CCNode作为容器容易踩的坑
  6. Seaborn绘图
  7. [转] C#2010 在TreeView控件下显示路径下所有文件和文件夹
  8. python查找文件相同的和包含汉字的
  9. C语言增量内存申请 realloc
  10. Elasticsearch-PHP 搜索操作