[CF160D](Edges in MST)

题意:给你一个无向带权图,求每一条边:

1.在每个最小生成树中.

2.在部分最小生成树中.

3.不在任何一个最小生成树中.

solution:

建立并查集

将每条边按边权从小到大排序:

如果一条边的两端都在同一联通块中则该边为none

但是any 怎么区分呢

这就要用到割边的知识

我们把每组权相等的边拿出来

重新建图 (tips:保留原有的联通块(连通块以其祖先标记)

tarjan跑割边,此时割边即为any

否则是at least one

code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 200005
using namespace std;
struct zero{
  int nxt,to,id;
}edge[N<<1];
int head[N],tot=0;
void add_edge(int a,int b,int c){
  edge[++tot]=(zero){head[a],b,c};
  head[a]=tot;
}
struct sett{
  int u,v,w,id;
}lib[N];
int n,m,f[N],ans[N];
int dfn[N],idx=0;
int tarjan(int x,int pre){
  int lowu=dfn[x]=++idx;
  for(int i=head[x];i!=-1;i=edge[i].nxt){
    int to=edge[i].to;
    if(!dfn[to]){
      int lowv=tarjan(to,i);
      if(lowv>=dfn[to])ans[edge[i].id]=1;
      lowu=min(lowu,lowv);
      }
    else if(dfn[to]<dfn[x]&&i!=(pre^1))lowu=min(lowu,dfn[to]);
    }
  return lowu;
  }
bool cmp(sett a,sett b){return a.w<b.w;}
int find(int k){return (f[k]==k)?k:f[k]=find(f[k]);}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1;i<=m;i++){
    scanf("%d%d%d",&lib[i].u,&lib[i].v,&lib[i].w);
    lib[i].id=i;
    }
  sort(lib+1,lib+m+1,cmp);
  for(int i=1;i<=m;i++)f[i]=i;
  int last;
  for(int i=1;i<=m;i++){
    last=i;
    while(last<=m&&lib[last].w==lib[i].w)last++;last--;
    for(int r=i;r<=last;r++){
      lib[r].u=find(lib[r].u);
      lib[r].v=find(lib[r].v);
      if(lib[r].u==lib[r].v){
        ans[lib[r].id]=-1;
        continue;
        }
      dfn[lib[r].u]=dfn[lib[r].v]=0;
      head[lib[r].u]=head[lib[r].v]=-1;
      }
    idx=0;tot=-1;
    for(int r=i;r<=last;r++)
      if(lib[r].u!=lib[r].v)
        add_edge(lib[r].u,lib[r].v,lib[r].id),
        add_edge(lib[r].v,lib[r].u,lib[r].id);
    for(int r=i;r<=last;r++)
      if(!dfn[lib[r].u])tarjan(lib[r].u,-1);
    for(int r=i;r<=last;r++){f[find(lib[r].u)]=find(lib[r].v);}
      i=last;
    }
  for(int i=1;i<=m;i++){
    if(ans[i]==-1)puts("none");
    else if(ans[i]==1)puts("any");
    else puts("at least one");
    }
  }
原文地址:https://www.cnblogs.com/stepsys/p/10374997.html