zoukankan      html  css  js  c++  java
  • 葡萄庄园 [图论]

    葡萄庄园



    color{red}{正解部分}

    答案肯定为 一种颜色联通块 和 另一种颜色联通块 的 的大小,
    中存在 “一座桥”, 可以让其中一个颜色通过, 联通两个联通块 .

    于是考虑先预处理出每个颜色的所有联通块的大小, 给每个不同的联通块分配一个编号, 大小记为 size[id]size[id],

    对一个询问 xx, 考虑求出 xx 所处的 33 种颜色联通块与其他颜色 最大, 设为 max_v[x]max\_v[x],

    则对一个点, 它 属于 它所在的 其中一个颜色联通块 和 另一个颜色联通块 的 ,
    所以枚举每个点, 使用这个点的权值去计算出每个联通块之间的 , 记为 intv[a,b]intv[a, b], 可以使用 std::map<int, ll> intv[] 存储 .

    接下来枚举开头提到的那座 “桥” u,vu, v, 再枚举两边联通块的颜色, 分别记为 a=id[u,1/2/3],b=id[v,1/2/3]a = id[u, 1/2/3], b = id[v, 1/2/3]
    在满足 这座 “桥” 允许其中一种颜色通过 的前提下, 使用 size[a]+size[b]intv[a,b]size[a] + size[b] - intv[a, b] 更新 u,vu,v 所在的对应联通块的答案 max_v[]max\_v[] .

    最后询问时, 枚举当前点的 33 种颜色的联通块, 取其中最大的 max_v[]max\_v[] 作为答案即可 .


    color{red}{实现部分}

    #include<bits/stdc++.h>
    #define reg register
    typedef long long ll;
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 100005;
    
    int N;
    int M;
    int num0;
    int Id_cnt;
    int A[maxn];
    int head[maxn];
    int vis[maxn][4];
    
    ll size[maxn];
    ll max_v[maxn];
    
    std::map <int, ll> intv[maxn];
    
    struct EDGE{ int u, v, w; } E[maxn];
    
    struct Edge{ int nxt, to, w; } edge[maxn << 1];
    
    void Add(int from, int to, int w){ edge[++ num0] = (Edge){ head[from], to, w }; head[from] = num0; }
    
    void DFS(int k, const int &col, const int &id){
            vis[k][col] = id, size[id] += A[k];
            for(reg int i = head[k]; i; i = edge[i].nxt){
                    int to = edge[i].to;
                    if(col == edge[i].w || vis[to][col]) continue ;
                    DFS(to, col, id);
            }
    }
    
    void Work(){
            ll Ans = 0; int x = read();
            for(reg int col = 1; col <= 3; col ++) Ans = std::max(Ans, max_v[vis[x][col]]);
            printf("%lld
    ", Ans);
    }
    
    int main(){
            N = read(), M = read();
            for(reg int i = 1; i <= N; i ++) A[i] = read();
            for(reg int i = 1; i <= M; i ++){
                    E[i].u = read(), E[i].v = read(), E[i].w = read();
                    Add(E[i].u, E[i].v, E[i].w), Add(E[i].v, E[i].u, E[i].w);
            }
            for(reg int col = 1; col <= 3; col ++)
                    for(reg int j = 1; j <= N; j ++)
                            if(!vis[j][col]) DFS(j, col, ++Id_cnt);
            for(reg int i = 1; i <= N; i ++)
                    for(reg int j = 3; j >= 1; j --)
                            for(reg int k = j-1; k >= 1; k --) 
                                    intv[vis[i][j]][vis[i][k]] += A[i], intv[vis[i][k]][vis[i][j]] += A[i];
            for(reg int i = 1; i <= M; i ++){
                    if(vis[E[i].u][E[i].w] == vis[E[i].v][E[i].w]) continue ;
                    for(reg int col = 1; col <= 3; col ++){
                            if(E[i].w == col) continue ;
                            int x = vis[E[i].u][E[i].w], y = vis[E[i].v][col]; 
                            max_v[x] = std::max(max_v[x], size[x] + size[y] - intv[x][y]); 
                            max_v[y] = std::max(max_v[y], size[x] + size[y] - intv[x][y]);
                            x = vis[E[i].v][E[i].w], y = vis[E[i].u][col];
                            max_v[x] = std::max(max_v[x], size[x] + size[y] - intv[x][y]); 
                            max_v[y] = std::max(max_v[y], size[x] + size[y] - intv[x][y]);
                    }
            }
            int Q_ = read(); 
            while(Q_ --) Work();
            return 0;
    }
    
  • 相关阅读:
    461. Hamming Distance
    342. Power of Four
    326. Power of Three
    368. Largest Divisible Subset java solutions
    95. Unique Binary Search Trees II java solutions
    303. Range Sum Query
    160. Intersection of Two Linked Lists java solutions
    88. Merge Sorted Array java solutions
    67. Add Binary java solutions
    14. Longest Common Prefix java solutions
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822441.html
Copyright © 2011-2022 走看看