codeforce 891 C

题链

对每个k值判是否成环。

正确性基于拟阵的性质(那个k开头的算法的正确性)。

#include <bits/stdc++.h>
#define N 500005
using namespace std;
int par[N],rk[N];
int root(int x){while(x^par[x]) x=par[x];return x;}
struct his{int u, rk1;int v, rk2;};
void unite(int x, int y){
    if(rk[x] > rk[y])par[y] = x;
    else{par[x] = y;if(rk[x] == rk[y])++rk[y];}
}
void divide(const his &x){
    par[x.u] = x.u;par[x.v] = x.v;
    rk[x.u] = x.rk1;rk[x.v] = x.rk2;
}
struct edge{
    int u, v, l;
}e[N];
int b[N];
his h[N];
struct qedge{
    int eid, qid;
}a[N];
bool cmp(int x, int y){return e[x].l < e[y].l;}
bool cmp2(const qedge &x, const qedge &y){return e[x.eid].l < e[y.eid].l || (e[x.eid].l == e[y.eid].l && x.qid < y.qid); }
bool ans[N];
int n,m,u,v,l;
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++){
        scanf("%d%d%d", &u, &v, &l);
        e[i] = {u, v, l};
        b[i] = i;
    }
    int q;
    scanf("%d", &q);
    int nqe = 0,k;
    for(int i = 0; i < q; i++){
        scanf("%d", &k);
        for(int j = 0; j < k; j++){
            int x;
            scanf("%d", &x);
            a[nqe++] = {x, i};
        }
    }
    sort(a, a + nqe, cmp2);
    for(int i = 1; i <= n; i++) par[i] = i;
    sort(b + 1, b + m + 1, cmp);
    for(int i = 1, j = 0; i <= m && j < nqe; ){
        for(; e[b[i]].l < e[a[j].eid].l; i++){
            int r1 = root(e[b[i]].u);
            int r2 = root(e[b[i]].v);
            if(r1 != r2)
                unite(r1, r2);
        }
        for(; j < nqe && e[a[j].eid].l == e[b[i]].l; ){
            int sz = 0;
            for(int k = a[j].qid; a[j].qid == k && e[a[j].eid].l == e[b[i]].l; j++){
                if(ans[k]) continue;
                auto &x = e[a[j].eid];
                int r1 = root(x.u), r2 = root(x.v);
                if(r1 == r2)
                    ans[k] = 1;
                else{
                    h[sz++] = {r1, rk[r1], r2, rk[r2]};
                    unite(r1, r2);
                }
            }
            for(int i=sz-1;~i;i--) divide(h[i]);
        }
    }
    for(int i = 0; i < q; i++)
        puts(ans[i] ? "NO" : "YES");
    return 0;
}
原文地址:https://www.cnblogs.com/rrsb/p/8343233.html