zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    一段获取windows环境变量的代码
    尝试word2007的blog发布
    如何求一表所有行所有字段实际占用的空间
    如何查询全表扫描SQL
    Oracle 33个等待事件
    如何使用RMAN
    如何使用Diagnostics工具监控应用服务器
    如何查询每行数据的数据块信息
    如何理解recursive calls,db block gets和consistent gets
    如何编写批处理与SQLPLUS(例子)
  • 原文地址:https://www.cnblogs.com/rrsb/p/8343233.html
Copyright © 2011-2022 走看看