zoukankan      html  css  js  c++  java
  • [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++
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    ActiveSync合作关系对话框的配置
    WINCE对象存储区(object store)
    Wince 隐藏TASKBAR的方法
    Wince输入法换肤换语言机制
    poj 3080 Blue Jeans 解题报告
    codeforces A. Vasily the Bear and Triangle 解题报告
    hdu 1050 Moving Tables 解题报告
    hdu 1113 Word Amalgamation 解题报告
    codeforces A. IQ Test 解题报告
    poj 1007 DNA Sorting 解题报告
  • 原文地址:https://www.cnblogs.com/GoldenPotato/p/8746852.html
Copyright © 2011-2022 走看看