[CF891C 부러워] [최소 스패닝 트리]

CF891C 질투

CF891C의 luogu

== YYB 보는 것입니다

  1. 어떤 에지 가중치를 들어, 모든 무게의 모서리의 수는 일정한 최소 스패닝 트리입니다
  2. 임의의 적절하게 마주 예를 들어, 소정의 중량 이하의 추가의 연결 그래프 에지 모두 완료 후에 동일한

동일한 값의 양면 함께 고려하여 주인이 그 고정하더라도 결과로부터 얻을 수있다

통신 블록의 측면에 접속

각 전처리 미만 \ (W_i는 \) 우측의 에지 가입 첨가 \을 (W_i \) 측 고리 기의 형성 후,이 쿼리가 실패하면

관해서는 제기 된 질문에 대해보고 할 == 복원 때마다 수정

#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef pair<int,int>pii;
const int N=5e5+5,M=5e5+5,inf=0x3f3f3f3f;
int n,m,s,tt,f[N];
template<class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct edge{
    int u,v,w,id;
    bool operator<(const edge&X)const{return w<X.w;}
}e[N],q[N];
bool cmp(edge X,edge Y){return X.id<Y.id;}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}

bool kruskal(){
    int K;rd(K);
    for(int i=1,x;i<=K;++i) rd(x),q[i]=e[x];
    sort(q+1,q+K+1);
    for(int i=1,j=1;i<=K;i=++j){
        while(j<K&&q[j+1].w==q[j].w) ++j;
        for(int k=i;k<=j;++k) f[q[k].u]=q[k].u,f[q[k].v]=q[k].v;
        for(int k=i;k<=j;++k){
            if(find(q[k].u)==find(q[k].v)) return 0;
            f[f[q[k].u]]=f[q[k].v];
        }
    }
    return 1;
}


int main(){
    freopen("in.txt","r",stdin);
    rd(n),rd(m);
    for(int i=1,u,v,w;i<=m;++i) rd(u),rd(v),rd(w),e[i]=(edge){u,v,w,i};
    for(int i=1;i<=n;++i) f[i]=i;
    sort(e+1,e+m+1);
    for(int i=1,j=1;i<=m;i=++j){
        while(j<m&&e[j+1].w==e[j].w) ++j;
        for(int k=i;k<=j;++k) e[k].u=find(e[k].u),e[k].v=find(e[k].v);
        for(int k=i;k<=j;++k)
        if(find(e[k].u)!=find(e[k].v)) f[f[e[k].u]]=f[e[k].v];
    }
    sort(e+1,e+m+1,cmp);
    rd(m);while(m--) puts(kruskal()?"YES":"NO");
    return 0;
}

추천

출처www.cnblogs.com/lxyyyy/p/11540391.html