• cf827D Best Edge Weight (kruskal+倍增lca+并查集)


    先用kruskal处理出一个最小生成树

    对于非树边,倍增找出两端点间的最大边权-1就是答案

    对于树边,如果它能被替代,就要有一条非树边,两端点在树上的路径覆盖了这条树边,而且边权不大于这条树边

    这里可以树剖来做,但是不想用..

    如果先把非树边从小到大排序然后去覆盖树边,那么一条树边只需要被覆盖一次

    所以可以用一个并查集来把父子边被覆盖的点合到一起,在合并之前记下来这次覆盖的边权,下次再覆盖的时候直接跳过去就可以

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define CLR(a,x) memset(a,x,sizeof(a))
      4 using namespace std;
      5 typedef long long ll;
      6 const int maxn=2e5+10,inf=1e9+1;
      7 
      8 inline ll rd(){
      9     ll x=0;char c=getchar();int neg=1;
     10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     12     return x*neg;
     13 }
     14 
     15 struct Edge{
     16     int a,b,l,ne;
     17     bool used;
     18 }eg[maxn],eg2[maxn*2];
     19 int egh[maxn],ect;
     20 int N,M,fa[maxn][20],bf[maxn],bm[maxn],ma[maxn][20],dep[maxn];
     21 int ans[maxn];
     22 
     23 inline int getf(int x){return bf[x]==x?x:bf[x]=getf(bf[x]);}
     24 inline bool cmp(Edge a,Edge b){return a.l<b.l;}
     25 inline void adeg(int a,int b,int c){
     26     eg2[++ect].b=b;eg2[ect].ne=egh[a];
     27     eg2[ect].l=c,egh[a]=ect;
     28 }
     29 
     30 void dfs(int x){
     31     // printf("!!%d %d %d
    ",x,fa[x][0],ma[x][0]);
     32     for(int i=0;fa[x][i]&&fa[fa[x][i]];i++)
     33         fa[x][i+1]=fa[fa[x][i]][i],ma[x][i+1]=max(ma[x][i],ma[fa[x][i]][i]);
     34     for(int i=egh[x];i;i=eg2[i].ne){
     35         int b=eg2[i].b;
     36         if(b==fa[x][0]) continue;
     37         ma[b][0]=eg2[i].l;
     38         fa[b][0]=x;dep[b]=dep[x]+1;
     39         dfs(b);
     40     }
     41 }
     42 
     43 int lca(int x,int y){
     44     if(dep[x]<dep[y]) swap(x,y);
     45     int re=0;
     46     for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){
     47         if(fa[x][i]&&dep[fa[x][i]]>=dep[y])
     48             re=max(re,ma[x][i]),x=fa[x][i];
     49     }
     50     if(x==y) return re;
     51     for(int i=log2(dep[x]);i>=0;i--){
     52         if(fa[x][i]!=fa[y][i])
     53             re=max(re,max(ma[x][i],ma[y][i])),x=fa[x][i],y=fa[y][i];
     54     }
     55     return max(re,max(ma[x][0],ma[y][0]));
     56 }
     57 
     58 int main(){
     59     //freopen("","r",stdin);
     60     int i,j,k;
     61     N=rd(),M=rd();
     62     for(i=1;i<=M;i++){
     63         eg[i].a=rd(),eg[i].b=rd(),eg[i].l=rd();
     64         eg[i].ne=i;
     65     }
     66     sort(eg+1,eg+M+1,cmp);
     67     for(i=1;i<=N;i++) bf[i]=i;
     68     for(i=1,j=0;i<=M&&j<N-1;i++){
     69         int a=getf(eg[i].a),b=getf(eg[i].b);
     70         if(a!=b){
     71             bf[a]=b;
     72             adeg(eg[i].a,eg[i].b,eg[i].l);
     73             adeg(eg[i].b,eg[i].a,eg[i].l);
     74             eg[i].l=inf;eg[i].used=1;
     75             j++;
     76         }
     77     }
     78     dep[1]=1;dfs(1);
     79     sort(eg+1,eg+M+1,cmp);
     80     for(i=1;i<=N;i++) bf[i]=i,bm[i]=inf;
     81     for(i=1;i<=M;i++){
     82         if(eg[i].used) continue;
     83         int a=getf(eg[i].a),b=getf(eg[i].b);
     84         while(a!=b){
     85             if(dep[a]<dep[b]) swap(a,b);
     86             int bb=getf(fa[a][0]);
     87             bf[a]=bb,bm[a]=eg[i].l;
     88             a=bb;
     89         }
     90     }
     91     for(i=1;i<=M;i++){
     92         if(eg[i].used){
     93             int a=eg[i].a,b=eg[i].b;
     94             if(dep[a]<dep[b]) swap(a,b);
     95             // a=getf(a),b=getf(b);
     96             if(bm[a]<inf) ans[eg[i].ne]=bm[a]-1;
     97             else ans[eg[i].ne]=-1;
     98         }else{
     99             ans[eg[i].ne]=lca(eg[i].a,eg[i].b)-1;
    100         }
    101     }
    102     for(i=1;i<=M;i++)
    103         printf("%d ",ans[i]);
    104     return 0;
    105 }
  • 相关阅读:
    MongoDB对集合分片
    将本地项目导入到PyCharm中
    安装docker-compose报错
    MySQL定时删除按日分表或者按月分表的表
    使用Navicat连接oracle
    MySQL Error_code: 1756
    Python logging模块
    PyCharm添加Liunx开发环境进行本地开发
    Java向上保留两位小数
    JAVA计算字符串UTF-8字节数
  • 原文地址:https://www.cnblogs.com/Ressed/p/9811368.html
Copyright © 2020-2023  润新知