描述

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

现在有W(3 <= W <= 2000)个供水站,其中最多有P(P <=20,000)< span=”“>条管道,每一条管道连接了两个水站,并且不存在一条管道连接同一个水站,两个水站之间最多只有一条管道。每条管道有一定的费用。请寻找第二便宜的连接方式,使所有的水站相连。

假设最便宜的方案有且只有一种,并且至少有两种可行的连接方案。所有的费用都不超过16位有符号整数。水站用1到W的自然数表示

输入

第一行:两个数W和P 第2~P+1行:每行描述了一条管道,有3个用空格分开的整数,前两个数表示管道连接的两个端点。第3个数是管道的费用

输出

仅一行,第二便宜的管道铺设费用

样例输入

5 7

1 2 3

2 3 4

1 4 7

2 4 11

2 5 9

5 4 5

3 5 8

样例输出

20

标签

USACO2002-OPEN-GREEN


自己yy了一个次小生成树的写法。

就是每次用一个 不在次小生成树中的边去更新答案。

代码:

#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 秘密的牛奶管道SECRET(次小生成树)的更多相关文章

  1. 「LOJ#10068」「一本通 3.1 练习 3」秘密的牛奶运输(次小生成树

    题目描述 Farmer John 要把他的牛奶运输到各个销售点.运输过程中,可以先把牛奶运输到一些销售点,再由这些销售点分别运输到其他销售点. 运输的总距离越小,运输的成本也就越低.低成本的运输是 F ...

  2. Lean Data Innovation Sharing Salon(2018.09.15)

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

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

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

  4. 2018.09.15点名器(简单dp)

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

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

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

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

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

  7. 2018.09.15 bzoj1977:次小生成树 Tree(次小生成树+树剖)

    传送门 一道比较综合的好题. 由于是求严格的次小生成树. 我们需要维护一条路径上的最小值和次小值. 其中最小值和次小值不能相同. 由于不喜欢倍增我选择了用树链剖分维护. 代码: #include< ...

  8. 2018.09.15 vijos1053Easy sssp(最短路)

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

  9. 2018.09.15 hdu3018Ant Trip(欧拉路)

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

随机推荐

  1. leetcode754

    class Solution { public: int reachNumber(int target) { // 理解这题的意思 这题就好做了 // 分析 首先考虑一种比较极端的情况 即一直向正方向 ...

  2. Delphi 解析HTML

    uses mshtml; IHTMLEleMent.ID; IHTMLEleMent.tagName; IHTMLEleMent.title;elmt._className;elmt.getAttri ...

  3. 前端-CSS-11-Z-index

    ---- z-index 这个东西非常简单,它有四大特性,每个特性你记住了,页面布局就不会出现找不到盒子的情况. z-index 值表示谁压着谁,数值大的压盖住数值小的, 只有定位了的元素,才能有z- ...

  4. SecureCRT去除关闭Session的确认窗口提示

  5. 【转】oracle 体系结构

    前几天面试的时候面试官才问过我Oracle的体系结构,让我在一张白纸上画出来.回头想想当时答得还不错,大部分内容都描述出来了,呵呵,刚才在网上看到一篇讲解ORACLE体系结构的文章,觉得不错,转过来存 ...

  6. The 2018 Nobel prizesThe Nobel prize for economics is awarded for work on the climate and economic growth

    The 2018 Nobel prizesThe Nobel prize for economics is awarded for work on the climate and economic g ...

  7. ASP.NETAutocomplete control

    分享一个Ajax autocomplete control, 原文链接:http://forums.asp.net/t/1157595.aspx 首先,引入ScriptManager <asp: ...

  8. spark UDF函数

    Spark(Hive) SQL中UDF的使用(Python):http://www.tuicool.com/articles/3yMBNb7

  9. Fiddler 捕获 nodejs 模拟的http请求

    1.设置Fiddler Tools->Options-> Connections Allow remote computers to connect: 2.nodejs 请求有多种 2.1 ...

  10. ubuntu安装谷歌拼音输入法

    在这篇教程中,我将告诉你如何在ubuntu系统上安装谷歌拼音输入法.谷歌拼音输入法有基于ibus框架的,也有基于fcitx框架的.我只演示fcitx框架下谷歌拼音输入法的安装,因为ibus框架的谷歌拼 ...