题目描述

小C最近学了很多最小生成树的算法,Prim算法、Kurskal算法、消圈算法等等。正当小C洋洋得意之时,小P又来泼小C冷水了。小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说:如果最小生成树选择的边集是EM,严格次小生成树选择的边集是ES,那么需要满足:(value(e)表示边e的权值) \sum_{e \in E_M}value(e)<\sum_{e \in E_S}value(e)∑e∈EM​​value(e)<∑e∈ES​​value(e)

这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。

输入格式

第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。

输出格式

包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)

输入输出样例

输入 #1复制

5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6 

输出 #1复制

11

说明/提示

数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。

题解

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
typedef long long ll;
using namespace std;
const int M=1e5+100;
ll n,m,res,ans=0x3f3f3f3f,mx;
int f[M],fa[25][M],dep[M];
ll d[2][25][M];
bool used[3*M],vis[M];
vector<int> a[M];
struct Edge
{int from, to;ll val;bool operator < (const Edge y){return val < y.val;}
} e[3*M];
int F(int x)
{if(f[x]==x)return x;return f[x]=F(f[x]);
}
void kruskal()  //kruskal 算最大生成树(已保证任意两点之间最小限重最优)
{sort(e,e+m);int lef=n-1;for(int i=1; i<=n; ++i)f[i]=i;for(int i=0; i<m && lef; ++i){int x=F(e[i].from),y=F(e[i].to);if(x!=y){f[x]=y;res+=e[i].val;used[i]=1;--lef;mx=max(mx, e[i].val);}}
}
void dfs(int x)     //深搜建树(可能不止一棵,因为数据未保证是连通图)
{vis[x]=true;for(int i=1; i<=23; ++i){fa[i][x]=fa[i-1][fa[i-1][x]];ll t1=d[0][i-1][x], t2=d[0][i-1][fa[i-1][x]];d[0][i][x]=max(t1, t2);d[1][i][x]=max(d[1][i-1][x], d[1][i-1][fa[i-1][x]]);if(t1!=t2)d[1][i][x]=max(d[1][i][x], min(t1, t2));}for(int i=0; i<a[x].size(); ++i){int t=e[a[x][i]].to+e[a[x][i]].from-x;if(vis[t])continue;    //vis为1表示是父节点dep[t]=dep[x]+1;fa[0][t]=x;d[0][0][t]=e[a[x][i]].val;dfs(t);}
}
int lca(int u,int v)
{if(dep[u]<dep[v])swap(u,v);if(dep[u]!=dep[v])      //将深度做相等{for(int i=23,h=dep[u]-dep[v]; i>=0; --i)if(h&(1<<i))u=fa[i][u];}if(u==v)return u;  //如果已经在一个节点上就直接返回for(int i=23; i>=0; --i)if(fa[i][u]!=fa[i][v])u=fa[i][u], v=fa[i][v];return fa[0][u];
}
ll get(int u,int v,int c)
{int fht=lca(u,v);ll m1=0,m2=0;for(int i=23,h1=dep[u]-dep[fht],h2=dep[v]-dep[fht]; i>=0; --i){if(h1&(1<<i)){if(d[0][i][u]>m1)m2=m1,m1=d[0][i][u];else if(d[0][i][u]>m2)m2=d[0][i][u];elsem2=max(m2, d[1][i][u]);}if(h2&(1<<i)){if(d[0][i][v]>m1)m2=m1,m1=d[0][i][v];else if(d[0][i][v]>m2)m2=d[0][i][v];elsem2=max(m2, d[1][i][v]);}}if(m1==c)return c-m2;elsereturn c-m1;
}
int main()
{scanf("%d%d",&n,&m);for(int i=0; i<m; ++i){int u,v;ll w;scanf("%d%d%lld",&u,&v,&w);e[i].from=u;e[i].to=v;e[i].val=w;}kruskal();for(int i=0; i<m; ++i)if(used[i]){a[e[i].from].push_back(i);a[e[i].to].push_back(i);}dep[1]=1;dfs(1);for(int i=0; i<m; ++i)if(!used[i]){if(e[i].val-mx>ans)break;ll t=get(e[i].from, e[i].to, e[i].val);ans=min(ans, t);}return printf("%lld\n",res+ans),0;
}

洛谷 P 4180 次小生成树相关推荐

  1. 洛谷P3379 【模板】最近公共祖先(LCA)

    洛谷P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数 ...

  2. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  3. 洛谷 P1142 轰炸

    洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...

  4. 洛谷 P1387 最大正方形

    P1387 最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=10 ...

  5. poj 1679 次小生成树

    次小生成树的求法: 1.Prime法 定义一个二维数组F[i][j]表示点i到点j在最小生成树中的路径上的最大权值.有个知识就是将一条不在最小生成树中的边Edge加入最小生成树时,树中要去掉的边就是E ...

  6. 洛谷P2763 试题库问题

    题目:https://www.luogu.org/problemnew/show/P2763 题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性. ...

  7. 动态规划——洛谷_P1057传球游戏

    题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...

  8. 洛谷P1417 烹调方案

    洛谷P1417 烹调方案 如果是一般的01背包的话 选的先后是没关系的 但是这题选的先后是有关系的,因为他的价值是随着时间而变化的, 而你的01背包是做不到先选2再选1的 那么我们就跟国王游戏一样 用 ...

  9. HDU4081(次小生成树)

    1.其中:枚举每条不在最小生成树上的边,并把这条边放到最小生成树上面,然后就一定形成环,那么我们将这条环中取出最长的一条路.最终我们得到的权值便是最小生成树的权值. Max[i][j]表示的最小生成树 ...

最新文章

  1. stm32 独立看门狗学习
  2. 使用反射把用户控件(ASCX)传至网页(ASPX)
  3. STM32F0使用LL库实现SHT70通讯
  4. 视频编解码(八):264/265解码器小结
  5. 章节十五、6-log4 2-用默认的配置
  6. 【运动学】基于matlab GUI模拟小球自由落体【含Matlab源码 1630期】
  7. 15 Android系统安全(简要)
  8. ASP.NET学习 asp‘s one word
  9. ctfmon.exe频繁出错的一个解决办法
  10. 定位算法——多边测量法及MATLAB编程
  11. 装机安装必备开发软件
  12. 维度表和事实表的区别
  13. PDF修改文字的步骤
  14. 杭州市公积金提取及相关知识
  15. python中的f函数_05-python中函数的使用
  16. C中的struct,union,Bit Filed以及内存对齐
  17. 人生苦短,我用Python,那么问题来了,普通人要学python吗?
  18. 12306订票候补是个坑_12306实现自动抢票了,候补购票功能在哪里,怎么用?
  19. 社交类app 乱弹琴
  20. 【Mysql数据库应用】

热门文章

  1. win7开机提示服务器正在运行,科技常识:win7电脑启动ie浏览器提示服务器正在运行的处理方法...
  2. iOS库--.a与.framework
  3. 菜单自定义图标_操作系统任务栏了解多少,Windows server 2008 R2自定义通知区域...
  4. iOS 常用公共方法
  5. linux之SQL语句简明教程---UNION ALL
  6. Java历程-初学篇 Day05选择结构(2)
  7. php 命令行方式运行时 几种传入参数的方式
  8. Redhat安装tftp的方法
  9. [最新下载] 【火车票订票外挂】Go-Home–12306.cn 网上火车票自动订票程序
  10. Sharepoint学习笔记---Sandbox Solution-- Full Trust Proxy--开发实例之(2、在Webpart中访问Full Trust Proxy)...