zoukankan      html  css  js  c++  java
  • CF E2

    http://codeforces.com/contest/1184/problem/E2

    题意:给出一副图,首先求出这幅图的最小生成树 , 然后修改这幅图上不属于最小生成树的边权,使得修改后的图在求一边生成树的时候可以包含被修改的边(注意:修改的边权要最大 )题目规定只有一课生成树

    分析:

    现在我们需要解决所有非树边的任务(MST保证是惟一的)。我们要求对于非树边(u, v),正确答案是u和v之间路径上的最大权值MST。(证明:≤:由MSTs的循环特性可知;≥:如果(u, v)的重量大于这个最大值,然后用(u, v)交换获得最大值的边,会得到一个更便宜的树a矛盾。

    所以现在我们的任务就是求任意两点在生成树上的路径最大边权。这题我们可以用LCA的思想去完成,我们现在预处理出了一条路上走过的最大值,那么答案所求mx=max(mx(u->w) , mx(v->w)) ;w为u,v的最近公共祖先,这里采用倍增法的思想去完成

    #include<bits/stdc++.h>
    using namespace std ;
    int n,m;
    const int maxn = 1e6+3;
    vector<pair<int,int> >G[maxn];
    int pre[maxn],fa[maxn][19],dep[maxn],mx[maxn][19],ans[maxn];
    struct no
    {
        int id,u,v,w;
    }a[maxn];
    bool cmp(no a , no b)
    {
        return a.w<b.w;
    }
    int ffind(int x)
    {
        if(pre[x]==x) return x;
        pre[x]=ffind(pre[x]);
        return pre[x];
    }
    void dfs(int u , int p)
    {
        for(int i=0 ; i<G[u].size() ; i++)
        {
            int v=G[u][i].first;
            if(p==v) continue;
            dep[v]=dep[u]+1;
            fa[v][0]=u;
            mx[v][0]=G[u][i].second;
            dfs(v,u);
        }
    }
    int lca(int u , int v)
    {
        if(dep[u]>dep[v]) swap(u,v);
        for(int i=0 ; i<18 ; i++)
        if((dep[v]-dep[u])&(1<<i)) v=fa[v][i];
        if(u==v) return u;
        for(int i=17 ; i>=0 ; i--)
        if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
        return fa[u][0];
    }
    int ask(int u , int st)
    {
        int ret=0;
        for(int i=0 ; i<18 ; i++)
        if(st&(1<<i)) ret=max(ret,mx[u][i]),u=fa[u][i];
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0 ; i<m ; i++)
        {
            a[i].id=i;
            scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
        }
        ///卡鲁思
        for(int i=1 ; i<=n ; i++) pre[i]=i;
        sort(a,a+m,cmp);
        for(int i=0 ; i<m ; i++)
        {
            int u=ffind(a[i].u) , v=ffind(a[i].v);
            if(u!=v)
            {
                pre[u]=v;
                ans[a[i].id]=-1;
                G[a[i].u].push_back({a[i].v,a[i].w});
                G[a[i].v].push_back({a[i].u,a[i].w});
            }
        }
        ///lca
        dep[1]=1; dfs(1,0);
        for(int i=1 ; i<18 ; i++)
        for(int j=1 ; j<=n ; j++)
        {
            fa[j][i]=fa[fa[j][i-1]][i-1];
            mx[j][i]=max(mx[j][i-1],mx[fa[j][i-1]][i-1]);
        }
        for(int i=0 ; i<m ; i++)
        if(ans[a[i].id]!=-1)
        {
            int u=a[i].u ,v=a[i].v , w=lca(u,v);
            ans[a[i].id]=max(ask(u,dep[u]-dep[w]),ask(v,dep[v]-dep[w]));
        }
        for(int i=0 ; i<m ; i++)
        {
            if(ans[i]!=-1)
            printf("%d ",ans[i]);
        }
    }
    View Code
  • 相关阅读:
    《Cracking the Coding Interview》——第11章:排序和搜索——题目8
    《Cracking the Coding Interview》——第11章:排序和搜索——题目7
    《Cracking the Coding Interview》——第11章:排序和搜索——题目6
    《Cracking the Coding Interview》——第11章:排序和搜索——题目5
    《Cracking the Coding Interview》——第11章:排序和搜索——题目4
    数据结构,体系结构,组成原理,高等数学
    配置TortoiseGit与Github
    生成模型(Generative)和判别模型(Discriminative)
    luogu P1037 产生数 x
    【説明する】グラフ理論
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/11150481.html
Copyright © 2011-2022 走看看