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;
}

  

posted @ 2015-03-11 00:50  雪溯  阅读(352)  评论(0编辑  收藏  举报