题目描述:

有一天,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);
}

 

XJOI 3629 非严格次小生成树(pqq的礼物)的更多相关文章

  1. Imperial roads 非严格次小生成树

    cf测评姬比uva快了五倍... /* 不管这条边是不是在mst上,直接跑lca求出路径上的最大边w即可 ans=mst-w+dist(u,v) */ #include<bits/stdc++. ...

  2. (luogu4180) [Beijing2010组队]次小生成树Tree

    严格次小生成树 首先看看如果不严格我们怎么办. 非严格次小生成树怎么做 由此,我们发现一个结论,求非严格次小生成树,只需要先用kruskal算法求得最小生成树,然后暴力枚举非树边,替换路径最大边即可. ...

  3. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  4. 严格次小生成树(Bzoj1977:[Beijing2010组队]次小生成树)

    非严格次小生成树 很简单,先做最小生成树 然后枚举没加入的边加入,替换掉这个环内最大的边 最后取\(min\) 严格次小生成树 还是一样的 可以考虑维护一个严格次大值 最大值和枚举的边相同就替换次大值 ...

  5. P4180 严格次小生成树[BJWC2010] Kruskal,倍增

    题目链接\(Click\) \(Here\). 题意就是要求一个图的严格次小生成树.以前被题面吓到了没敢做,写了一下发现并不难. 既然要考虑次小我们就先考虑最小.可以感性理解到一定有一种次小生成树,可 ...

  6. 算法笔记--次小生成树 && 次短路 && k 短路

    1.次小生成树 非严格次小生成树:边权和小于等于最小生成树的边权和 严格次小生成树:    边权和小于最小生成树的边权和 算法:先建好最小生成树,然后对于每条不在最小生成树上的边(u,v,w)如果我们 ...

  7. 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  8. 【luogu P4180 严格次小生成树[BJWC2010]】 模板

    题目链接:https://www.luogu.org/problemnew/show/P4180 这个题卡树剖.记得开O2. 这个题inf要到1e18. 定理:次小生成树和最小生成树差距只有在一条边上 ...

  9. BZOJ 1977 严格次小生成树

    小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小 ...

随机推荐

  1. apache 自定义404错误页面

    1.有些提供web服务的网站,在用户访问一个不存在的网站文件时,会提示404错误,如下所示: 现在要求自定义一个错误页面,也就是出现404错误代码时,跳转到我们自定义的网址上.下面记录下方法: 1.编 ...

  2. **__new__和__init__

    这个__new__之前在写单例模式的时候用到过,下面做个深入了解吧. __new__是一个静态方法,而__init__是一个实例方法. __new__方法会返回一个创建的实例,而__init__什么都 ...

  3. JNI 里使用STL

    JNI里的c或者c++ 调用stl 的时候,比如引入map头文件: #include <map> 在cygwin使用NDK编译的时候,会提示: fatal error:map: No su ...

  4. 10分钟.Net Core 简单入门教程

    以 Centos 为例 1.安装所需的依赖关系 打开命令提示符并运行以下命令: sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/p ...

  5. Eclipse修改tomcat初始分配空间参数

    正常启动tomcat后,运行报java.lang.OutOfMemoryError: PermGen space,查阅是tomcat内存溢出,也就是分配给tomcat的永久内存小了点 在Eclipse ...

  6. [iOS]隐藏导航栏把右滑退出操作保留

    项目因为用到上面导航栏样式多变,就隐藏了导航栏自己用View代替了,但手势却不见了,后来发现问题解决.操作如下: 千万不要取消 Shows Navigation Bar 这个选项否则手势会消失 应该是 ...

  7. 清除html中的标记,只留下文字

    /// <summary>/// 清除html中的标记,只留下文字./// </summary>/// <param name="HTML">& ...

  8. screen command of linux

    [screen command of linux] 常用键:   补充: Ctrl-a S  # split terminal horizon Ctrl-a TAB   # switch to ano ...

  9. 实现SwipeRefreshLayout首次进入自动刷新

    看到了Android版知乎实现了这种效果,就自己也实现了一下. 先来一张效果图 实现方式: 方法一. ①在onWindowFocusChanged()方法中,设置为刷新状态为true @Overrid ...

  10. MonoBehaviour.print和Debug.Log是同样的作用

    MonoBehaviour.print("identical------------------------");