[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