zoukankan      html  css  js  c++  java
  • BZOJ 1977 次小生成树(最近公共祖先)

    题意:求一棵树的严格次小生成树,即权值严格大于最小生成树且权值最小的生成树。

    先求最小生成树,对于每个不在树中的边,取两点间路径的信息,如果这条边的权值等于路径中的权值最大值,那就删掉路径中的次大值,加上这条非树边,更新答案;否则删掉路径中的最大值,加上这条非树边,更新答案。

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 #define ll long long
      7 struct edge{
      8     int u,v,id;
      9     ll w;
     10 }e[300005];
     11 int tot,go[600005],first[300005],next[600005];
     12 ll val[600005];
     13 int fa[100005][18],deep[100005],F[100005],bin[105],n,m;
     14 ll mx1[100005][18],mx2[100005][18],ans1,ans2;
     15 int read(){
     16     char ch=getchar();int t=0,f=1;
     17     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     18     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
     19     return t*f;
     20 }
     21 ll Read(){
     22     char ch=getchar();ll t=0,f=1;
     23     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     24     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
     25     return t*f;
     26 }
     27 bool cmp(edge a,edge b){
     28     return a.w<b.w;
     29 }
     30 void insert(int x,int y,ll z){
     31     tot++;
     32     go[tot]=y;
     33     next[tot]=first[x];
     34     first[x]=tot;
     35     val[tot]=z;
     36 }
     37 void add(int x,int y,int z){
     38     insert(x,y,z);insert(y,x,z);
     39 }
     40 int find(int x){
     41     if (F[x]==x) return x;
     42     else return (find(F[x]));
     43 }
     44 void up(ll x,ll &y){
     45     if (x>y) y=x;
     46 }
     47 void work(int x,int i){
     48      mx1[x][i]=std::max(mx1[fa[x][i-1]][i-1],mx1[x][i-1]);
     49      if (mx1[fa[x][i-1]][i-1]<mx1[x][i]) up(mx1[fa[x][i-1]][i-1],mx2[x][i]);
     50      if (mx1[x][i-1]<mx1[x][i]) up(mx1[x][i-1],mx2[x][i]);
     51      up(mx2[x][i-1],mx2[x][i]);
     52      up(mx2[fa[x][i-1]][i-1],mx2[x][i]);
     53 }
     54 void dfs(int x,int f){
     55     for (int i=1;i<=17;i++)
     56      fa[x][i]=fa[fa[x][i-1]][i-1],work(x,i);
     57     for (int i=first[x];i;i=next[i]){
     58         int pur=go[i];
     59         if (pur==f) continue;
     60         deep[pur]=deep[x]+1;
     61         fa[pur][0]=x;
     62         mx1[pur][0]=val[i];
     63         mx2[pur][0]=0;
     64         dfs(pur,x);
     65     } 
     66 }
     67 void up(ll x,ll &a,ll &b){
     68     if (x>a) b=a,a=x;
     69     else
     70     if (x>b&&x<a) b=x;
     71 }
     72 void lca(int x,int y){
     73     ans1=0,ans2=0;
     74     if (deep[x]<deep[y]) std::swap(x,y);
     75     int t=deep[x]-deep[y];
     76     for (int i=0;i<=17;i++)
     77      if (t&bin[i]) {
     78      up(mx1[x][i],ans1,ans2);
     79      up(mx2[x][i],ans1,ans2);
     80      x=fa[x][i];
     81      }
     82     for (int i=17;i>=0;i--)
     83      if (fa[x][i]!=fa[y][i]) {
     84             up(mx1[x][i],ans1,ans2);
     85             up(mx2[x][i],ans1,ans2);
     86             up(mx1[y][i],ans1,ans2);
     87             up(mx2[y][i],ans1,ans2);   
     88             x=fa[x][i];
     89             y=fa[y][i];
     90      }
     91     if (x!=y){
     92         up(mx1[x][0],ans1,ans2);
     93         up(mx2[x][0],ans1,ans2);
     94         up(mx1[y][0],ans1,ans2);
     95         up(mx2[y][0],ans1,ans2);  
     96     }
     97 }
     98 int main(){
     99     bin[0]=1;
    100     for (int i=1;i<=17;i++) bin[i]=bin[i-1]*2;
    101     n=read();m=read();
    102     for (int i=1;i<=m;i++){
    103         e[i].u=read();
    104         e[i].v=read();
    105         e[i].w=Read();
    106         e[i].id=0;
    107     }
    108     for (int i=1;i<=n;i++)
    109      for (int j=0;j<=17;j++)
    110       mx1[i][j]=mx2[i][j]=0;
    111     std::sort(e+1,e+1+m,cmp);
    112     ll sum=0;
    113     for (int i=1;i<=n;i++) F[i]=i;
    114     for (int i=1;i<=m;i++)
    115      if (find(e[i].u)!=find(e[i].v)){
    116         F[find(e[i].u)]=find(e[i].v);    
    117         e[i].id=1;
    118         add(e[i].u,e[i].v,e[i].w);
    119         sum+=e[i].w;
    120      }
    121     dfs(1,0);
    122     ll Ans=10000000000000000LL;
    123     for (int i=1;i<=m;i++)
    124      if (!e[i].id){
    125             lca(e[i].u,e[i].v);
    126             if (e[i].w==ans1) Ans=std::min(Ans,sum-ans2+e[i].w);
    127             else Ans=std::min(Ans,sum-ans1+e[i].w);
    128      }
    129     printf("%lld
    ",Ans);
    130 }
  • 相关阅读:
    global mapper合并多个tif影像
    arcgis 10.2 licence manager无法启动
    Error C2079 'CMFCPropertySheet::m_wndOutlookBar' uses undefined class 'CMFCOutlookBar'
    家里的技嘉B360主板win10 uefi系统安装
    vc 6.0项目转为vs 2017项目遇到 的问题
    PPT学习笔记
    git拉取分支
    将本地源码推向gitee码云
    java反编译工具使用记录
    node.js install and cecium apply
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5535947.html
Copyright © 2011-2022 走看看