博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BJOI 2010]次小生成树Tree
阅读量:5241 次
发布时间:2019-06-14

本文共 3141 字,大约阅读时间需要 10 分钟。

Description

小 C 最近学了很多最小生成树的算法,Prim 算法、Kurskal 算法、消圈算法等等。 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了。小 P 说,让小 C 求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说: 如果最小生成树选择的边集是 EM,严格次小生成树选择的边集是 ES,那么需要满足:(value(e) 表示边 e的权值)  这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。

Input

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

Output

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

Sample Input

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

Sample Output

11

Hint

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

题解

次小生成树模板。简便地直接用$LCA$做。唯一注意的是由于它要求严格的次小生成树,所以我们$LCA$时还要记得保存次大值。(防止边权相等)

1 #include  2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #define LL long long 13 using namespace std; 14 const LL N=100000; 15 16 LL n,m,op,x,y,p,q,d=2e15; 17 struct aa 18 { 19 LL u,v,c; 20 }lin[N*3+5]; 21 bool comp(aa a,aa b); 22 23 LL mst,cnt; 24 struct bb 25 { 26 LL to,next,cost; 27 }edge[N*2+5]; 28 LL path[N+5],top; 29 bool vis[N*3+5]; 30 void Add(LL u,LL v,LL c); 31 32 LL set[N+5]; 33 LL Find(LL x); 34 35 LL f[N+5][20],maxn[N+5][20],sub[N+5][20]; 36 LL dep[N+5]; 37 void Dfs(LL x,LL depth); 38 void Lca(LL x,LL y,LL c); 39 40 int main() 41 { 42 scanf("%lld%lld",&n,&m); 43 op=log2(n); 44 for (LL i=1;i<=m;i++) scanf("%lld%lld%lld",&lin[i].u,&lin[i].v,&lin[i].c); 45 sort(lin+1,lin+m+1,comp); 46 for (LL i=1;i<=m;i++) 47 { 48 p=Find(lin[i].u); 49 q=Find(lin[i].v); 50 if (p!=q) 51 { 52 set[p]=q; 53 cnt++; 54 mst+=lin[i].c; 55 vis[i]=1; 56 Add(lin[i].u,lin[i].v,lin[i].c); 57 Add(lin[i].v,lin[i].u,lin[i].c); 58 if (cnt==n-1) break; 59 } 60 } 61 if (cnt
p){maxn[i][t]=x;sub[i][t]=max(p,y);} 76 else if (x
=0;i--) if (dep[x]-(1<
=dep[y])108 {109 if (sub[x][i]>m1){m2=m1;m1=sub[x][i];}110 else if (sub[x][i]>m2&&sub[x][i]!=m1) m2=sub[x][i];111 if (maxn[x][i]>m1){m2=m1;m1=maxn[x][i];}112 else if (maxn[x][i]>m2&&maxn[x][i]!=m1) m2=maxn[x][i];113 x=f[x][i];114 }115 if (x!=y)116 {117 for (LL i=op;i>=0;i--) if (f[x][i]!=f[y][i])118 {119 if (sub[x][i]>m1){m2=m1;m1=sub[x][i];}120 else if (sub[x][i]>m2&&sub[x][i]!=m1) m2=sub[x][i];121 if (maxn[x][i]>m1){m2=m1;m1=maxn[x][i];}122 else if (maxn[x][i]>m2&&maxn[x][i]!=m1) m2=maxn[x][i];123 if (sub[y][i]>m1){m2=m1;m1=sub[y][i];}124 else if (sub[y][i]>m2&&sub[y][i]!=m1) m2=sub[y][i];125 if (maxn[y][i]>m1){m2=m1;m1=maxn[y][i];}126 else if (maxn[y][i]>m2&&maxn[y][i]!=m1) m2=maxn[y][i];127 x=f[x][i];128 y=f[y][i];129 }130 if (sub[x][0]>m1){m2=m1;m1=sub[x][0];}131 else if (sub[x][0]>m2&&sub[x][0]!=m1) m2=sub[x][0];132 if (maxn[x][0]>m1){m2=m1;m1=maxn[x][0];}133 else if (maxn[x][0]>m2&&maxn[x][0]!=m1) m2=maxn[x][0];134 if (sub[y][0]>m1){m2=m1;m1=sub[y][0];}135 else if (sub[y][0]>m2&&sub[y][0]!=m1) m2=sub[y][0];136 if (maxn[y][0]>m1){m2=m1;m1=maxn[y][0];}137 else if (maxn[y][0]>m2&&maxn[y][0]!=m1) m2=maxn[y][0];138 }139 if (m1==0) return;140 if (c==m1)141 {142 if (m2==0) return;143 d=min(d,c-m2);144 }145 else d=min(d,c-m1);146 }

 

转载于:https://www.cnblogs.com/NaVi-Awson/p/7252318.html

你可能感兴趣的文章
数值计算中,浮点类型给我们挖的坑
查看>>
(String)、toString、String.valueOf
查看>>
mongodb命令----批量更改文档字段名
查看>>
python多线程下载网页图片并保存至特定目录
查看>>
《人工智能的未来》--------------经典语录
查看>>
了解循环队列的实现
查看>>
CentOS 简单命令
查看>>
Linux中修改docker镜像源及安装docker
查看>>
数位dp(模板+例题)
查看>>
javascript中强制类型转换
查看>>
python学习笔记
查看>>
php+ajax(jquery)的文件异步上传
查看>>
使用&nbsp;SharedPreferences 分类: Andro...
查看>>
TLA+(待续...)
查看>>
c#数据结构(第四章)
查看>>
PHP 小方法之 计算两个时间戳之间相差的日时分秒
查看>>
python selenium 基本常用操作
查看>>
用ping命令简单的测试 延时、抖动、丢包率
查看>>
题解: [GXOI/GZOI2019]与或和
查看>>
camon详细解决过程
查看>>