话说这个[BeiJing2010组队]是个什喵玩意?

这是一道严格次小生成树,而次小生成树的做法是层出不穷的

MATO IS NO.1 的博客里对两种算法都有很好的解释,值得拥有:  (果然除我以外,所有自称傻 X 的都是神犇喵~)

  http://www.cppblog.com/MatoNo1/archive/2011/05/29/147627.aspx

MATO还讲了一个神级复杂度的次小生成树:  (请全部读完。如果被坑,后果自负)

  http://www.cppblog.com/MatoNo1/archive/2011/11/16/149812.html

如果你可以打开人人网的话(你懂的喵~),这也是篇很好的博文:

  http://blog.renren.com/share/235365847/6633394303

该说的都在上面了,我就扔扔代码吧  (高能勿喷)

 #include <cstdio>
#include <algorithm>
typedef long long llint;
const int inf=0x7FFFFFFF;
const int sizeOfN=;
const int sizeOfM=; namespace IOspace
{
inline int getint()
{
register int num=;
register char ch;
do ch=getchar(); while (ch<'' || ch>'');
do num=num*+ch-'', ch=getchar(); while (ch>='' && ch<='');
return num;
}
inline void putint(llint num, char ch='\n')
{
char stack[];
register int top=;
if (num==) stack[top=]='';
for ( ;num;num/=) stack[++top]=num%+'';
for ( ;top;top--) putchar(stack[top]);
if (ch) putchar(ch);
}
} int N, M; struct node {int u, v, c;};
node a[sizeOfM];
bool b[sizeOfM];
inline bool operator < (node i, node j)
{return i.c<j.c;} struct edge {int point, dist; edge * next;};
edge MEM[sizeOfM], * PORT=MEM;
edge * E[sizeOfN];
inline edge * newedge(int _point, int _dist, edge * _next)
{edge * ret=PORT++; ret->point=_point; ret->dist=_dist; ret->next=_next; return ret;}
inline void build(int u, int v, int c)
{E[u]=newedge(v, c, E[u]); E[v]=newedge(u, c, E[v]);} int r[sizeOfN];
int find(int x) {return r[x]==x?x:r[x]=find(r[x]);} int f[sizeOfN][], l[][sizeOfN][], h[sizeOfN];
bool vis[sizeOfN];
int top, stack[sizeOfN]; edge * temp[sizeOfN];
inline void search(); inline int max(int x, int y) {return x>y?x:y;}
inline int min(int x, int y) {return x<y?x:y;}
inline void swap(int & x, int & y) {int t=x; x=y; y=t;}
inline int lg(int x) {int i; for (i=;x>;i++) x>>=; return i;}
inline int lowbit(int x) {return x & -x;}
inline int lca(int, int, int);
inline llint kurskal();
inline void prepare();
inline int calc(); int main()
{
llint ans=; N=IOspace::getint(); M=IOspace::getint();
for (int i=;i<M;i++) a[i].u=IOspace::getint(), a[i].v=IOspace::getint(), a[i].c=IOspace::getint(); ans=kurskal();
prepare();
ans+=calc(); IOspace::putint(ans); return ;
}
inline void search()
{
f[][]=; h[]=;
for (stack[++top]=, temp[top]=E[];top; )
{
int & u=stack[top]; edge *& i=temp[top];
if (!vis[u]) vis[u]=;
for ( ;i;i=i->next) if (!vis[i->point])
{
f[i->point][]=u; h[i->point]=h[u]+;
l[][i->point][]=i->dist; l[][i->point][]=-inf;
stack[++top]=i->point; temp[top]=E[i->point];
break;
}
if (i) continue;
top--;
}
}
inline llint kurskal()
{
llint ret=;
int tot=N-; std::sort(a, a+M);
for (int i=;i<=N;i++) r[i]=i; for (int i=;i<M;i++)
{
int u=find(a[i].u), v=find(a[i].v);
if (u!=v)
{
build(a[i].u, a[i].v, a[i].c); ret+=a[i].c;
b[i]=;
r[u]=v;
if (!--tot) break;
}
} return ret;
}
inline void prepare()
{
search();
for (int j=;j<;j++)
for (int i=;i<=N;i++) if (h[i]>=(<<j))
{
f[i][j]=f[f[i][j-]][j-];
l[][i][j]=l[][i][j-]; l[][i][j]=l[][i][j-];
if (l[][f[i][j-]][j-]>l[][i][j]) l[][i][j]=l[][i][j], l[][i][j]=l[][f[i][j-]][j-];
else if (l[][f[i][j-]][j-]<l[][i][j])
if (l[][f[i][j-]][j-]>l[][i][j]) l[][i][j]=l[][f[i][j-]][j-];
}
}
inline int lca(int u, int v, int x)
{
int ret=-, dis; if (h[u]<h[v]) swap(u, v);
while (dis=h[u]-h[v])
{
int up=lg(lowbit(dis));
ret=max(ret, l[l[][u][up]==x][u][up]);
u=f[u][up];
}
if (u==v) return ret; for (int i=;i>=;i--)
if (f[u][i]!=f[v][i])
{
ret=max(ret, l[l[][u][i]==x][u][i]);
ret=max(ret, l[l[][v][i]==x][v][i]);
u=f[u][i]; v=f[v][i];
}
ret=max(ret, l[l[][u][]==x][u][]);
ret=max(ret, l[l[][v][]==x][v][]); return ret;
}
inline int calc()
{
int ret=inf;
for (int i=;i<M;i++)
if (!b[i])
ret=min(ret, a[i].c-lca(a[i].u, a[i].v, a[i].c));
return ret;
}

本傻装B系列

写的比树套树还长,真是没脸见人了喵~

[BeiJing2010组队][BZOJ 1977]次小生成树 Tree的更多相关文章

  1. BZOJ 1977 次小生成树(最近公共祖先)

    题意:求一棵树的严格次小生成树,即权值严格大于最小生成树且权值最小的生成树. 先求最小生成树,对于每个不在树中的边,取两点间路径的信息,如果这条边的权值等于路径中的权值最大值,那就删掉路径中的次大值, ...

  2. BZOJ 1977 次小生成树

    TM终于过了.... #include<iostream> #include<cstdio> #include<cstring> #include<algor ...

  3. BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )

    做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...

  4. 1977: [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree https://lydsy.com/JudgeOnline/problem.php?id=1977 题意: 求严格次小生成树,即边权和不 ...

  5. [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 5168  Solved: 1668[S ...

  6. 【BZOJ1977】[BeiJing2010组队]次小生成树 Tree 最小生成树+倍增

    [BZOJ1977][BeiJing2010组队]次小生成树 Tree Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C ...

  7. BZOJ 1977[BeiJing2010组队]次小生成树 Tree - 生成树

    描述: 就是求一个次小生成树的边权和 传送门 题解 我们先构造一个最小生成树, 把树上的边记录下来. 然后再枚举每条非树边(u, v, val),在树上找出u 到v 路径上的最小边$g_0$ 和 严格 ...

  8. 【刷题】BZOJ 1977 [BeiJing2010组队]次小生成树 Tree

    Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...

  9. 洛谷P4180【Beijing2010组队】次小生成树Tree

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

随机推荐

  1. 在T-SQL中访问远程数据库(openrowset、opendatasource、openquery)

    1.  启用Ad Hoc Distributed Queries 在使用openrowset/opendatasource前要先启用Ad Hoc Distributed Queries服务,因为这个服 ...

  2. centos下安装node js

    #wget http://nodejs.org/dist/v0.10.24/node-v0.10.24.tar.gz #tar xf node-v0.10.24.tar.gz #cd node-v0. ...

  3. hdu4417 划分树+二分

    //Accepted 14796 KB 453 ms //划分树 //把查询的次数m打成n,也是醉了一晚上!!! //二分l--r区间第k大的数和h比较 #include <cstdio> ...

  4. c++高质量编程手册

    怡化主管强烈要求我读这本书.... 笔记尚未完成,持续更新呗.. 第1章 高质量软件开发之道 1.1 软件质量基本概念 1.1.1 如何理解软件的质量:功能性和非公能性 1.1.2 提高软件质量的基本 ...

  5. MATLAB里的正则表达式 [转]

    正则表达式在处理字符串及文本时显得十分方便,在perl, python等脚本语言,以及java, .net等平台上都支援正则表达式.事实上,在MATLAB中也提供了正则表达式的支持.主要包含三个常用的 ...

  6. linux基础命令(二)用户管理和权限管理

  7. IOS之Core Foundation框架和Cocoa Foundation框架的区别

    Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...

  8. Windows下adb push 总是提示Failed to copy "XX.apk" to 'system/app':Read-only file system

    一般情况看到这种提示我们会想到需要root权限,然后敲上adb remount,但是当我们执行过adb remount后,提示成功,但执行push命令依旧无法完成push. 那么此时我们的做法应该是重 ...

  9. BZOJ 2111 排列计数

    f[i]=f[l]*f[r]*C(size[l]+size[r],size[l]). 需要lucas. #include<iostream> #include<cstdio> ...

  10. Brute-force Algorithm_矩阵快速幂&&欧拉公式*****

    Problem Description Professor Brute is not good at algorithm design. Once he was asked to solve a pa ...