传送门

一道比较综合的好题。

由于是求严格的次小生成树。

我们需要维护一条路径上的最小值和次小值。

其中最小值和次小值不能相同。

由于不喜欢倍增我选择了用树链剖分维护。

代码:

#include<bits/stdc++.h>
#define N 100005
#define M 300005
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
#define ll long long
#define xx first
#define yy second
using namespace std;
inline ll read(){
    ll ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
int first[N],cnt=0,n,m,sizz=0,Fa[N],fa[N],hson[N],dep[N],siz[N],top[N],num[N],pred[N];
bool vis[M];
ll sum=0,ans=1e18,a[N];
struct edge{int v,next;ll w;}e[N<<1];
struct Edge{int u,v;ll w;}t[M];
struct Node{int l,r;ll mx,sx;}T[N<<2];
inline bool cmp(Edge a,Edge b){return a.w<b.w;}
inline int find(int x){return x==Fa[x]?Fa[x]:Fa[x]=find(Fa[x]);}
inline void add(int u,int v,ll w){e[++cnt].v=v,e[cnt].w=w,e[cnt].next=first[u],first[u]=cnt;}
inline void kruskal(){
    int tot=0;
    for(int i=1;i<=n;++i)Fa[i]=i;
    sort(t+1,t+m+1,cmp);
    for(int i=1;i<=m;++i){
        if(tot==n-1)break;
        int fx=find(t[i].u),fy=find(t[i].v);
        if(fx!=fy)vis[i]=true,Fa[fx]=fy,sum+=t[i].w,++tot,add(t[i].u,t[i].v,t[i].w),add(t[i].v,t[i].u,t[i].w);
    }
}
inline void dfs1(int p){
    siz[p]=1;
    for(int i=first[p];i;i=e[i].next){
        int v=e[i].v;
        if(v==fa[p])continue;
        dep[v]=dep[p]+1,fa[v]=p,a[v]=e[i].w,dfs1(v),siz[p]+=siz[v];
        if(siz[v]>siz[hson[p]])hson[p]=v;
    }
}
inline void dfs2(int p,int tp){
    top[p]=tp,pred[num[p]=++sizz]=p;
    if(!hson[p])return;
    dfs2(hson[p],tp);
    for(int i=first[p];i;i=e[i].next){
        int v=e[i].v;
        if(v==fa[p]||v==hson[p])continue;
        dfs2(v,v);
    }
}
inline ll max(ll a,ll b){return a>b?a:b;}
inline void pushup(int p){
    T[p].mx=max(T[lc].mx,T[rc].mx);
    T[p].sx=max(T[p].mx==T[lc].mx?T[lc].sx:T[lc].mx,T[p].mx==T[rc].mx?T[rc].sx:T[rc].mx);
}
inline void build(int p,int l,int r){
    T[p].l=l,T[p].r=r;
    if(l==r){T[p].mx=a[pred[l]],T[p].sx=-1;return;}
    build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline pair<ll,ll> query(int p,int ql,int qr){
    if(T[p].r<ql||T[p].l>qr)return make_pair(0,-1);
    if(ql<=T[p].l&&T[p].r<=qr)return make_pair(T[p].mx,T[p].sx);
    if(qr<=mid)return query(lc,ql,qr);
    if(ql>mid)return query(rc,ql,qr);
    pair<ll,ll>ans1=query(lc,ql,mid),ans2=query(rc,mid+1,qr),ans;
    ans.xx=max(ans1.xx,ans2.xx);
    ans.yy=max(ans1.xx==ans.xx?ans1.yy:ans1.xx,ans2.xx==ans.xx?ans2.yy:ans2.xx);
    return ans;
}
inline pair<ll,ll> ask(int x,int y){
    pair<ll,ll>ret=make_pair(0,-1),tmp1,tmp2;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])x^=y,y^=x,x^=y;
        tmp1=query(1,num[top[x]],num[x]),tmp2=ret;
        ret.xx=max(tmp1.xx,tmp2.xx);
        ret.yy=max(ret.xx==tmp1.xx?tmp1.yy:tmp1.xx,ret.xx==tmp2.xx?tmp2.yy:tmp2.xx);
        x=fa[top[x]];
    }
    if(dep[x]<dep[y])x^=y,y^=x,x^=y;
    tmp1=query(1,num[y]+1,num[x]),tmp2=ret;
    ret.xx=max(tmp1.xx,tmp2.xx);
    ret.yy=max(ret.xx==tmp1.xx?tmp1.yy:tmp1.xx,ret.xx==tmp2.xx?tmp2.yy:tmp2.xx);
    return ret;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=m;++i)t[i].u=read(),t[i].v=read(),t[i].w=read();
    kruskal(),dfs1(1),dfs2(1,1),build(1,1,n);
    for(int i=1;i<=m;++i){
        if(vis[i])continue;
        int u=t[i].u,v=t[i].v;
        ll w=t[i].w;
        pair<ll,ll>tmp=ask(u,v);
        if(w!=tmp.xx)ans=min(ans,sum-tmp.xx+w);
        else if(tmp.yy!=-1)ans=min(ans,sum-tmp.yy+w);
    }
    cout<<ans;
    return 0;
}

2018.09.15 bzoj1977:次小生成树 Tree(次小生成树+树剖)的更多相关文章

  1. Lean Data Innovation Sharing Salon(2018.09.15)

    时间:2018.09.15地点:北京国华投资大厦

  2. 2018.09.15 秘密的牛奶管道SECRET(次小生成树)

    描述 约翰叔叔希望能够廉价连接他的供水系统,但是他不希望他的竞争对手知道他选择的路线.一般这样的问题需要选择最便宜的方式,所以他决定避免这种情况而采用第二便宜的方式. 现在有W(3 <= W & ...

  3. 2018.09.15模拟总结(T1,T3)

    过了一周,终于迎来了第二次模拟(这不是期待的语气),看第一周毒瘤程度,我就觉得接下来的模拟只能更毒瘤. 花了10多分钟读完了三道题,觉得暴力还是挺好写的,然后在每一道题都思索那么几分钟后,觉得还是写暴 ...

  4. 2018.09.22 atcoder Integers on a Tree(构造)

    传送门 先考虑什么时候不合法. 第一是考虑任意两个特殊点的权值的奇偶性是否满足条件. 第二是考虑每个点的取值范围是否合法. 如果上述条件都满足的话就可以随便构造出一组解. 代码: #include&l ...

  5. 2018.09.15点名器(简单dp)

    描述 Ssoier在紧张的学习中,杜老师每天给他们传授精妙的知识. 杜老师为了活跃气氛,设计了一个点名器,这个点名器包含一个长度为M的数组(下标1开始),每个元素是一个oier的名字,每次点名的时候, ...

  6. 2018.09.15 poj1734Sightseeing trip(floyd求最小环)

    跟hdu1599差不多.. 只是需要输出方案. 这个可以递归求解. 代码: #include<iostream> #include<cstdio> #include<cs ...

  7. 2018.09.15 hdu1599find the mincost route(floyd求最小环)

    传送门 floyd求最小环的板子题目. 就是枚举两个相邻的点求最小环就行了. 代码: #include<bits/stdc++.h> #define inf 0x3f3f3f3f3f3f ...

  8. 2018.09.15 vijos1053Easy sssp(最短路)

    传送门 貌似可以最短路时同时判定负环啊. 但我不想这样做. 于是写了一个dfs版的判环,bfs版的求最短路. 代码: #include<iostream> #include<ccty ...

  9. 2018.09.15 hdu3018Ant Trip(欧拉路)

    传送门 显然答案等于各个连通分量的笔画数之和. 因此我们dfs每个连通分量计算对答案的贡献. 对于一个连通分量,如果本来就有欧拉回路那么只需要一笔. 否则需要寄点数/2那么多笔才能画完. 知道这个结论 ...

随机推荐

  1. leetcode167

    public class Solution { public int[] TwoSum(int[] numbers, int target) { Dictionary<int, int> ...

  2. 1.Log4j入门

    转自:https://blog.csdn.net/luohai859/article/details/52250807 日志是应用软件中不可缺少的部分, .Apache的开源项目log4j是一个功能强 ...

  3. 怎样在Windows本地搭建redis服务器

    1.下载最新redis       https://github.com/MicrosoftArchive/redis/releases 2.解压如果是mis 版本直接下一步下一步即可 3.接下来我们 ...

  4. 解决Linux命令行为什么变成-bash-3.2$

    在Linux服务器上创建了一个新用户probe,是这样创建的: [root@localhost home]# groupadd -g 501 probe [root@localhost home]# ...

  5. 查看RPM包里的内容

    有时候,拿到一个RPM,并不想安装它,而想了解包里的内容,怎么办呢? 如果只相知道包里的文件列表执行: #rpm -qpl packetname 如果想要导出包里的内容,而不是安装,那么执行: # r ...

  6. oc 中的id类型与类型转换

    id是oc语言中一个独特的数据类型.一种通用对象类型.可以转换为任何数据类型,即id类型的变量可以存放任何数据类型的对象. 使用示例: Animal * dog = [[Dog alloc]init] ...

  7. deb软件包安装和卸载

    deb包是debian,ubuntu等LINUX发行版的软件安装包,是类似于rpm的软件包,而非debian,ubuntu系统不推荐使用deb软件包,因为要解决软件包依赖问题,安装也比较麻烦. 1.一 ...

  8. Pandas缺失数据处理

    Pandas缺失数据处理 Pandas用np.nan代表缺失数据 reindex() 可以修改 索引,会返回一个数据的副本: df1 = df.reindex(index=dates[0:4], co ...

  9. python集合的交,差,并,补集合运算汇总

    集合操作实际用的不多,了解即可. 交集:          ( & 或者 intersection ) 并集:    ( | 或者 union ) 差集:   ( -  或者  differe ...

  10. 双活部署前收集EMC存储设备信息

    以0.68服务器为例 1.拷贝emcgrab_Linux_v4.7.10.tar到linux服务器并将其解压到/tmp目录下 tar -xvf emcgrab_Linux_v4.7.10.tar -C ...