zoukankan      html  css  js  c++  java
  • 2020/8/26

    英语四级

    学习了kruskal重构树+dfs板的lca

    mad dfs的lca竟然会快一点 

    #include"stdio.h"
    #include"string.h"
    #include"stack"
    #include"map"
    #include"math.h"
    #include"iostream"
    #include"vector"
    #include"queue"
    #include"algorithm"
    using namespace std;
    #pragma GCC optimize(2)
    
    inline int read() {
        int x = 0;
        bool f = 1;
        char c = getchar();
        for (; !isdigit(c); c = getchar())
            if (c == '-')
                f = 0;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        if (f)
            return x;
        return 0 - x;
    }
    
    const int N = 300100;
    const int mod = 1e9 + 7;
    typedef struct Node{
        int x,y,w;
    }Node;
    Node node[N];
    int head[N],ver[N << 1],Next[N << 1],Edge[N << 1],tot;
    int n,m,top;
    int far[N],w[N];
    int A,B,C,P;
    
    int k,t;
    int id[N],d[N];
    int f[N][20];
    int lg[N];
    
    inline int rnd(){return A=(A*B+C)%P;}
    
    inline void add(int x,int y){
        ver[++ tot] = y; Next[tot] = head[x]; head[x] = tot;
    }
    
    bool cmp(Node a,Node b){
        return a.w < b.w;
    }
    
    inline int Find(int x){
        if(!far[x]) return x;
        return far[x] = Find(far[x]);
    }
    /*
    inline void bfs(int x){
        queue<int> Q;Q.push(x);
        d[x] = 1;
        while(!Q.empty()){
            int x = Q.front(); Q.pop();
            for(int i = head[x]; i; i = Next[i]){
                int y = ver[i];
                if(d[y]) continue;
                d[y] = d[x] + 1;
                f[y][0] = x;
                for(int j = 1; j <= t; j ++)
                    f[y][j] = f[f[y][j - 1]][j - 1];
                Q.push(y);
            }
        }
    }
    inline int lca(int x,int y){
        if(d[x] > d[y]) x ^= y ^= x ^= y;
        for(int i = t; i >= 0; i --)
            if(d[f[y][i]] >= d[x]) y = f[y][i];
        if(x == y) return x;
        for(int i = t; i >= 0; i --)
            if(f[x][i] != f[y][i]) x = f[x][i],y = f[y][i];
        return f[x][0];
    }*/
    void dfs(int cur, int fath) {
            f[cur][0] = fath; d[cur] = d[fath] + 1;
            for (int i = 1; i <= lg[d[cur]]; ++i)
                    f[cur][i] = f[f[cur][i - 1]][i - 1];
    
            for (int i = head[cur]; i ; i = Next[i])
                    if (ver[i] != fath)
                            dfs(ver[i], cur);
    }
    int lca(int x, int y) {
            if (d[x] < d[y]) swap(x, y);
            while (d[x] > d[y])
                    x = f[x][lg[d[x] - d[y]] - 1];
            if (x == y)
                    return x;
    
            for (int i = lg[d[x]] - 1; i >= 0; --i)
                    if (f[x][i] != f[y][i])
                            x = f[x][i], y = f[y][i];
            return f[x][0];
    }
    int main(){
        n = read(); m = read();
        for(int i = 1; i <= m; i ++){
            node[i].x = read(); node[i].y = read();node[i].w = read();
        }
        sort(node + 1,node + m + 1,cmp);
        top = n;
        for(int i = 1; i <= m; i ++){
            int x = node[i].x,y = node[i].y;
            int fx = Find(x),fy = Find(y);
            if(fx == fy) continue;
            w[++ top] = node[i].w;
            add(top,fx); //add(fx,top);
            add(top,fy); //add(fy,top);
            far[fx] = top;
            far[fy] = top;
            if(top  == 2 * n - 1) break;
        }
        for (int i = 1; i < N; ++i)
                    lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
        dfs(top, 0);
        int q = read();
        A = read(); B = read(); C = read(); P = read();
        int s = 0;
        while(q --){
            int u=rnd()%n+1,v=rnd()%n+1;
            int fa = lca(u,v);
            if(u != v)
            s += w[fa];
            if(s >= mod) s -= mod;
        }
        printf("%d
    ",s);
    }
    /*
    3
    1 2 3
    2
    2 6
    */
    
    #include"stdio.h"
    #include"string.h"
    #include"stack"
    #include"map"
    #include"math.h"
    #include"iostream"
    #include"vector"
    #include"queue"
    #include"algorithm"
    using namespace std;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int s = 0, w = 1; char ch = getchar();
        while(ch < '0' || ch > '9')   { if(ch == '-') w = -1; ch = getchar(); }
        while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); }
        return s * w;
    }
    
    const int N = 300100;
    int head[N],ver[N << 1],Next[N << 1],Edge[N << 1],tot;
    int n,m;
    int visit[N],match[N];
    
    
    void add(int x,int y){
        ver[++ tot] = y; Next[tot] = head[x]; head[x] = tot;
    }
    
    bool dfs(int x){
        for(int i = head[x]; i; i = Next[i]){
           int y = ver[i];
           if(visit[y]) continue;
           visit[y] = 1;
           if(!match[y] || dfs(match[y])){
            match[y] = x; return true;
           }
        }
        return false;
    }
    int main(){
        int T = read();
        while(T --){
            n = read(); m = read();
            tot = 0;
            memset(head,0,sizeof(head));
            memset(match,0,sizeof(match));
            for(int i = 1; i <= m; i ++){
                int x = read(),y = read();
                add(x,y + n);
            }
            int ans = 0;
            for(int i = 1; i <= n + n; i ++){
                memset(visit,0,sizeof(visit));
                if(dfs(i)) ans ++;
            }
            //ans /= 2;
            printf("%d
    ",n - ans);
        }
    }
    /*
    3
    1 2 3
    2
    2 6
    */
    
    
    #include"stdio.h"
    #include"string.h"
    #include"stack"
    #include"map"
    #include"math.h"
    #include"iostream"
    #include"vector"
    #include"queue"
    #include"algorithm"
    using namespace std;
    #pragma GCC optimize(2)
    
    inline int read() {
        int x = 0;
        bool f = 1;
        char c = getchar();
        for (; !isdigit(c); c = getchar())
            if (c == '-')
                f = 0;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        if (f)
            return x;
        return 0 - x;
    }
    
    const int N = 300100;
    const int mod = 1e9 + 7;
    typedef struct Node{
        int x,y,w;
    }Node;
    Node node[N * 3];
    int head[N],ver[N << 1],Next[N << 1],Edge[N << 1],tot;
    int n,m,top;
    int far[N],w[N];
    int high[N],b[N],len;
    int k,t;
    int id[N],d[N];
    int f[N][20];
    int lg[N];
    int root[N << 5],sum[N << 5],lc[N << 5],rc[N << 5],tot1;
    int son[N][2],num,h[N],tt;
    
    inline void add(int x,int y){
        ver[++ tot] = y; Next[tot] = head[x]; head[x] = tot;
    }
    
    bool cmp(Node a,Node b){
        return a.w < b.w;
    }
    
    inline int Find(int x){
        if(!far[x]) return x;
        return far[x] = Find(far[x]);
    }
    void dfs(int cur, int fath) {
            f[cur][0] = fath; d[cur] = d[fath] + 1;
            for (int i = 1; i <= lg[d[cur]]; ++i)
                    f[cur][i] = f[f[cur][i - 1]][i - 1];
    
            for (int i = head[cur]; i ; i = Next[i])
                    if (ver[i] != fath)
                            dfs(ver[i], cur);
    }
    
    void Build_Tree(int &rt,int l,int r){
        rt = ++ tot1; sum[rt] = 0;
        if(l == r) return ;
        int mid = (l + r) >> 1;
        Build_Tree(lc[rt],l,mid);
        Build_Tree(rc[rt],mid + 1,r);
    }
    void Update(int pre,int &rt,int l,int r,int v){
        rt = ++ tot1;
        lc[rt] = lc[pre]; rc[rt] = rc[pre]; sum[rt] = sum[pre] + 1;
        if(l == r) return ;
        int mid = (l + r) >> 1;
        if(mid >= v) Update(lc[pre],lc[rt],l,mid,v);
        else Update(rc[pre],rc[rt],mid + 1,r,v);
    }
    int query(int u,int v,int l,int r,int k){
    
        int mid = (l + r) >> 1;
        int x = sum[rc[v]] - sum[rc[u]];
       // printf("v = %d u = %d l = %d r = %d k = %d x = %d
    ",v,u,l,r,k,x);
        if(l == r) {
            if(k - (sum[v] - sum[u]) == 0)
                return l;
        return 0;
        }
        if(x >= k) return query(rc[u],rc[v],mid + 1,r,k);
        else return query(lc[u],lc[v],l,mid,k - x);
    }
    void dfs1(int x,int far){
        son[x][0] = num;
        if(head[x] == 0){
            son[x][0] = ++ num;
            int id = lower_bound(b + 1,b + len + 1,high[x]) - b;
            h[++ tt] = id;
            return ;
        }
        for(int i = head[x]; i; i = Next[i]){
            int y = ver[i];
            if(far == y) continue;
            dfs1(y,x);
        }
        son[x][1] = num;
    }
    int main(){
        n = read(); m = read(); int q = read();
        for(int i = 1; i <= n; i ++) b[i] = high[i] = read();
        sort(b + 1,b + n + 1);
        len = unique(b + 1,b + n + 1) - b - 1;
        for(int i = 1; i <= m; i ++){
            node[i].x = read(); node[i].y = read();node[i].w = read();
        }
        sort(node + 1,node + m + 1,cmp);
        top = n;
        for(int i = 1; i <= m; i ++){
            int x = node[i].x,y = node[i].y;
            int fx = Find(x),fy = Find(y);
            if(fx == fy) continue;
            w[++ top] = node[i].w;
            add(top,fx); //add(fx,top);
            add(top,fy); //add(fy,top);
            far[fx] = top;
            far[fy] = top;
            if(top  == 2 * n - 1) break;
        }
        for (int i = 1; i < N; ++i)
            lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
        t = (int)(log(top) / log(2)) + 1;
        dfs(top, 0);
        dfs1(top,1);
        Build_Tree(root[0],1,len);
       // printf("tot1 = %d
    ",tot1);
        for(int i = 1; i <= n; i ++){
          //  printf("h = %d
    ",h[i]);
            Update(root[i - 1],root[i],1,len,h[i]);
        }
     //   printf("tot1 = %d
    ",tot1);
        b[0] = -1;
        while(q --){
            int u = read(),x = read(),k = read();
            for(int i = 20; i >= 0; i --){
                if(f[u][i] && w[f[u][i]] <= x) u = f[u][i];
            }
            if(w[u] == 0){
                if(k == 1) printf("%d
    ",high[u]);
                else printf("-1
    "); continue;
            }
          //  printf("u = %d
    ",u);
           // printf("l = %d r = %d root[l] = %d root[r] = %d
    ",son[u][0],son[u][1],root[son[u][0]],root[son[u][1]]);
            if(son[u][1] - son[u][0] < k) printf("-1
    ");
            else{
              int s = query(root[son[u][0]],root[son[u][1]],1,len,k);
              printf("%d
    ",b[s]);
            }
        }
    }
    /*
    3
    1 2 3
    2
    2 6
    */
    

      

  • 相关阅读:
    protobuf 一个c++示例
    protobuf 之 MessageLite 接口摘录
    export setenv
    Centos java 安装
    C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用
    centos 安装tkdiff
    Redis 入门指南
    VB.NET+三层 机房收费系统之组合查询
    Android studio 插件之 GsonFormat (自己主动生成javabean)
    ubuntu14.04恢复系统默认中文字体
  • 原文地址:https://www.cnblogs.com/yrz001030/p/13568322.html
Copyright © 2011-2022 走看看