• [CF160D]Edges in MST (最小生成树+LCA+差分)


    待填坑

    Code

    //CF160D Edges in MST
    //Apr,4th,2018
    //树上差分+LCA+MST
    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    long long read()
    {
        long long x=0,f=1; char c=getchar();
        while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    const int N=100000+1000;
    struct line
    {
        int s,t,w1,w,ans,no;
    }e[N];
    struct edge
    {
        int t,w,no;
    };
    bool cmp(line a,line b)
    {
        return a.w1<b.w1;
    }
    bool cmp2(line a,line b)
    {
        return a.no<b.no;
    }
    vector <edge> r[N];
    struct mrk
    {
        int num,count;
    };
    vector <mrk> mk[N];
    int n,m;
    bool IsOnMST[N];
    int fa[N][21],mx[N][21],d[N],mark[N];
    bool visited[N];
    void dfs(int now,int depth)
    {
        visited[now]=true;
        d[now]=depth;
        for(int i=1;i<=20;i++)
        {
            fa[now][i]=fa[fa[now][i-1]][i-1];
            mx[now][i]=max(mx[now][i-1],mx[fa[now][i-1]][i-1]);
        }
        int to=r[now].size();
        for(int i=0;i<to;i++)
            if(visited[r[now][i].t]==false)
            {
                fa[r[now][i].t][0]=now;
                mx[r[now][i].t][0]=r[now][i].w;
                dfs(r[now][i].t,depth+1);
            }
    }
    int LCA(int x,int y,int &MAX)
    {
        if(d[x]<d[y])
            swap(x,y);
        for(int i=20;i>=0;i--)
            if(d[fa[x][i]]>=d[y])
            {
                MAX=max(MAX,mx[x][i]);
                x=fa[x][i];
            }
        if(x==y) return x;
        for(int i=20;i>=0;i--)
            if(fa[x][i]!=fa[y][i])
            {
                MAX=max(MAX,mx[x][i]);
                MAX=max(MAX,mx[y][i]);
                x=fa[x][i],y=fa[y][i];
            }
        MAX=max(MAX,mx[x][0]);
        MAX=max(MAX,mx[y][0]);
        return fa[x][0];
    }
    int FA[N];
    inline int FindFather(int x)
    {
        if(FA[x]==0) return x;
        return FA[x]=FindFather(FA[x]);
    }
    void MST()
    {
        sort(e+1,e+1+m,cmp);
        for(int i=1;i<=m;i++)
            if(e[i].w1!=e[i-1].w1)
                e[i].w=e[i-1].w+1;
            else
                e[i].w=e[i-1].w;
        int tot=0;
         for(int i=1;i<=m;i++)
        {
            int f1=FindFather(e[i].s),f2=FindFather(e[i].t);
            if(f1!=f2)
            {
                FA[f1]=f2;
                r[e[i].s].push_back((edge){e[i].t,e[i].w,i});
                r[e[i].t].push_back((edge){e[i].s,e[i].w,i});
                IsOnMST[i]=true;
                tot++;
                e[i].ans=2;
            }
            if(tot==n-1)
                break;
        }
    }
    void dfs2(int now)
    {
        visited[now]=true;
        for(int i=0;i<int(r[now].size());i++)
            if(visited[r[now][i].t]==false)
            {
                int stm=mark[r[now][i].w];
                dfs2(r[now][i].t);
                if(mark[r[now][i].w]-stm>0)
                    e[r[now][i].no].ans=1;
            }
        for(int i=0;i<int(mk[now].size());i++)
            mark[mk[now][i].num]+=mk[now][i].count;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++)
            mk[i].reserve(4),
            r[i].reserve(4);
        for(int i=1;i<=m;i++)
            e[i].s=read(),e[i].t=read(),e[i].w1=read(),e[i].no=i;
        
        MST();
        dfs(1,1);
        
        for(int i=1;i<=m;i++)
            if(IsOnMST[i]==false)
            {
                int MAX=0,lca=LCA(e[i].s,e[i].t,MAX);
                if(MAX==e[i].w) 
                {
                    e[i].ans=1;
                    mk[e[i].s].push_back((mrk){MAX,1});
                    mk[e[i].t].push_back((mrk){MAX,1});
                    mk[lca].push_back((mrk){MAX,-2});
                }
            }
            
        memset(visited,0,sizeof visited);
        dfs2(1);
            
        sort(e+1,e+1+m,cmp2);
        for(int i=1;i<=m;i++)
            if(e[i].ans==0)
                printf("none
    ");
            else if(e[i].ans==1)
                printf("at least one
    ");
            else
                printf("any
    ");
        return 0;
    }
    C++
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    False注入,以及SQL注入技巧总结
    xdebug插件攻击
    RPO攻击
    教务处sso设计缺陷
    MD5的Hash长度扩展攻击
    AMAZON PRICE TRACKER, AMAZON PRICE HISTORY, AMAZON PRICE DROP ALERT | DROPGG.COM
    弄懂JDK、JRE和JVM之间的联系。
    MyBatis配置及学习
    Cannot forward after response has been committed 异常原因
    bbs论坛中的问题和心得。(更新)
  • 原文地址:https://www.cnblogs.com/GoldenPotato/p/8746852.html
Copyright © 2020-2023  润新知