话说这个[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. elementoryOS / ubuntu U盘启动问题的解决

    具体现象: 进入U盘启动后,停顿在"start booting from usb device..."不动. 解决方法:  将syslinux文件夹下的syslinux.cfg中的 ...

  2. vector中的元素删除

    删除vector中的元素,最容易的方法就是使用vector的erase()函数. vector vec;for ( vector::iterator iter = vec.begin(); iter! ...

  3. hadoop shell 操作命令

    shell操作命令: hdfs的路径,在core-site.xml中定义 <property> <name>fs.default.name</name> <v ...

  4. JVM-class文件完全解析-常量池

    在.java文件,讲过javac编译后产生的 .class文件中,头4个字节表示的是魔数,接着魔数后面的第5,6个字节存储的是次版本号,第7,8个字节存储的主板本号.那么再接下来的就是表示常量池入口了 ...

  5. Activity(活动)-再讲

    通过多天的学习,大家也了解了adb.exe 是用来进行 客户端(pc)-服务器端(android) 数据交互的. 用户可以使用工具Eclipse 中DDMS 隐示使用  adb.exe 进行连接,也可 ...

  6. CSS练习一(模仿163邮箱登陆)

    // '); code = code.replace(/&/g, '&'); return code; }; var runCode = function (code) { if (c ...

  7. acm 20140825

    为了自己的梦想,一次次的选择坚强.走上acm这条路,怎么也找不到让自己放弃的理由.我喜欢这种竞赛的氛围,我渴望在赛场上飞扬!想想过去的一个学习,自己并没有干点什么有意义的事.acm也没有好好的做!新的 ...

  8. Android SurfaceView vs TextureView

    Android SurfaceView vs TextureView https://github.com/crosswalk-project/crosswalk-website/wiki/Andro ...

  9. Android IPC(inter-process Communitcation)

    Android IPC(inter-process Communitcation) http://www.cnblogs.com/imlucky/archive/2013/08/08/3246013. ...

  10. C++11 std::copy

    这个函数并不是简单的 while(first != last) { *result = *first; result++; first++; } 事实上这种写法是最具普适性的,值要求inputIter ...