zoukankan      html  css  js  c++  java
  • CF1108F MST Unification(生成树+思维)

    首先做一遍最小生成树,其次,如果某条未在生成树当中的边可以替换端点之间的边的话,那么证明它存在新的最小生成树。

    因此我们要将这条的权值加到比路径上的最大边大1的情况,才能做到这条边无用

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=4e5+10;
    int h[N],ne[N],e[N],w[N],idx;
    int depth[N],f[N][30];
    ll cost[N][30];
    int st[N];
    struct node{
        ll a,b,c;
    }s[N];
    int n,m;
    int p[N];
    void add(int a,int b,int c){
        e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
    }
    bool cmp(node a,node b){
        return a.c<b.c;
    }
    void dfs(int u,int fa,int x){
        depth[u]=depth[fa]+1;
        f[u][0]=fa;
        cost[u][0]=x;
        int i;
        for(i=1;i<=24;i++){
            f[u][i]=f[f[u][i-1]][i-1];
            cost[u][i]=max(cost[f[u][i-1]][i-1],cost[u][i-1]);
        }
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            dfs(j,u,w[i]);
        }
    }
    int find(int x){
        if(p[x]!=x){
            p[x]=find(p[x]);
        }
        return p[x];
    }
    void kruscal(){
        int i;
        for(i=1;i<=n;i++)
            p[i]=i;
        sort(s+1,s+1+m,cmp);
        int cnt=0;
        for(i=1;i<=m;i++){
            int pa=find(s[i].a);
            int pb=find(s[i].b);
            if(pa!=pb){
                p[pa]=pb;
                add(s[i].a,s[i].b,s[i].c);
                add(s[i].b,s[i].a,s[i].c);
                cnt++;
                st[i]=1;
            }
            if(cnt==n-1)
                break;
        }
        dfs(1,0,0);
    }
    ll lca(int a,int b){
        if(depth[a]<depth[b])
            swap(a,b);
        ll res=0;
        int i;
        for(i=21;i>=0;i--){
            if(depth[f[a][i]]>=depth[b]){
                res=max(res,cost[a][i]);
                a=f[a][i];
            }
        }
        if(a==b)
            return res;
        for(i=21;i>=0;i--){
            if(f[a][i]!=f[b][i]){
                res=max(res,cost[a][i]);
                res=max(res,cost[b][i]);
                a=f[a][i];
                b=f[b][i];
            }
        }
        return max(res,max(cost[a][0],cost[b][0]));
    }
    int main(){
        ios::sync_with_stdio(false);
        memset(h,-1,sizeof h);
        int i;
        cin>>n>>m;
        for(i=1;i<=m;i++){
            int a,b,c;
            cin>>a>>b>>c;
            s[i]={a,b,c};
        }
        kruscal();
        ll ans=0;
        for(i=1;i<=m;i++){
            if(st[i])
                continue;
            int a=s[i].a,b=s[i].b;
            ll x=lca(a,b);
            if(x==s[i].c){
                ans++;
            }
        }
        cout<<ans<<endl;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    百度mp3地址解密码
    VB 在EXE后附加信息
    截屏函数
    Base64和StrToByte
    The Android ION memory allocator, DMABUF is mentioned as well
    DDC EDID 介绍
    Memory management for graphic processors TTM的由来
    科普 写display driver的必看 How video card works [2D的四种主要操作]
    GEM vs TTM
    DMABUF 背景介绍文章 Sharing buffers between devices
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13698926.html
Copyright © 2011-2022 走看看