• CF 160D Edges in MST 最小生成树的性质,寻桥,缩点,批量处理 难度:3


    http://codeforces.com/problemset/problem/160/D

    这道题要求哪条边存在于某个最小生成树中,哪条边不存在于最小生成树中,哪条边绝对存在于最小生成树中

    明显桥边一定存在于所有最小生成树中,然而怎么处理存在某个最小生成树的边呢?

    借助kruskal算法的性质,由小到大,每次处理同一权值的边,如果边连接的点已经联通就不要管,否则那些处理的边一定存在于某最小生成树上

    批量处理的思想很巧妙

    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <algorithm>
    using namespace std;
    const int maxn=2e5+5;
    int first[maxn];
    struct edge{
            int t,ind,nxt;
    }e[maxn];
    int from[maxn],to[maxn],cost[maxn],index[maxn];
    int sta[maxn];
    int n,m,len;
    
    void addedge(int f,int t,int ind,int i){
            e[i].nxt=first[f];
            first[f]=i;
            e[i].t=t;
            e[i].ind=ind;
    }
    int par[maxn],num[maxn];
    int fnd(int x){return par[x]==x?x:par[x]=fnd(par[x]);}
    void unit(int a,int b){
            if(fnd(a)==fnd(b))return;
            num[fnd(b)]+=num[fnd(a)];
            num[fnd(a)]=0;
            par[fnd(a)]=fnd(b);
    }
    bool cmp(int a,int b) {return cost[a]<cost[b];}
    
    int dfn[maxn],low[maxn],cnt;
    void dfs(int s,int f){
            dfn[s]=low[s]=++cnt;
            for(int p=first[s];p!=0;p=e[p].nxt){
                    int t=e[p].t;
                    if(p==(((f-1)^1)+1))continue;
                    if(dfn[t]==0){
                            dfs(t,p);
                            if(low[t]>dfn[s]){
                                    sta[e[p].ind]=2;
                            }
                            else{
                                    low[s]=min(low[s],low[t]);
                            }
                    }
                    else {
                            low[s]=min(low[s],dfn[t]);
                    }
            }
    }
    
    int st[maxn],tail;
    void kruskal2(){
            sort(index,index+m,cmp);
            for(int i=0;i<m&&num[fnd(1)]<n;){
                    int j=i;
                    while(cost[index[i]]==cost[index[j]]&&j<m){j++;}
                    for(int k=i;k<j;k++){
                            int indk=index[k];
                            if(fnd(from[indk])!=fnd(to[indk])){
                                    st[tail++]=indk;
                                    sta[indk]=1;
                            }
                    }
                    for(int p=0;p<tail;p++){
                            int tp=st[p];
                            int f=fnd(from[tp]),t=fnd(to[tp]);
                            addedge(f,t,tp,++len);
                            addedge(t,f,tp,++len);
                    }
                    for(int p=0;p<tail;p++){
                            int tp=st[p];
                            int f=fnd(from[tp]),t=fnd(to[tp]);
                            dfs(f,0);
                            unit(f,t);
                    }
                    cnt=0;
                    len=0;
                    for(int p=0;p<tail;p++){
                            int tp=st[p];
                            int f=fnd(from[tp]),t=fnd(to[tp]);
                            first[f]=first[t]=0;
                            dfn[f]=dfn[t]=0;
                    }
    
                    i=j;
                    tail=0;
            }
    }
    
    
    int main(){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){par[i]=i;num[i]=1;}
    
            for(int i=0;i<m;i++){
                    scanf("%d%d%d",from+i,to+i,cost+i);
                    index[i]=i;
            }
            kruskal2();
    
    
            for(int i=0;i<m;i++){
                    if(sta[i]==2)puts("any");
                    else if(sta[i]==1)puts("at least one");
                    else puts("none");
            }
            return 0;
    }
    

      

  • 相关阅读:
    Scala的基本类型和操作
    spark-submit部署应用的相关参数详解
    Spark的相关概念说明和检查点机制
    解决网站需要cookies登录和内容需要动态加载问题
    python 多线程
    re
    echarts中的图表大小自适应
    git过滤提交文件
    响应式媒体
    爬过的坑
  • 原文地址:https://www.cnblogs.com/xuesu/p/4328851.html
Copyright © 2020-2023  润新知