zoukankan      html  css  js  c++  java
  • HDU4467 Grahp(分块)

    这道题与HDU4858 项目管理一样,都是分为轻重点,因为这样只会最多遍历sqrt条边,但是这题需要合并重边,不然复杂度会走样

    分块的思想真的很强大。对于轻点来说,暴力遍历更新答案和重信息,而对于重点来说,只需要更新相邻重点。这样做是正确的是因为重点的信息都会由轻点和重点更新,而轻点是暴力,肯定正确。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    const int  N=1e5+10;
    ll ans[5],a[N];
    ll sum[N][2];
    int st[N];
    int in[N];
    int n,m;
    int cnt;
    struct node{
        int a,b;
        ll v;
        bool operator <(const node &t){
            if(a==t.a)
                return b<t.b;
            return a<t.a;
        }
    }s[N];
    struct Edge{
        int u;
        ll v;
    };
    vector<Edge> g[N];
    int main(){
        int h=0;
        while(cin>>n>>m){
            int i;
            for(i=1;i<=n;i++){
                sum[i][0]=sum[i][1]=0;
                in[i]=0;
                g[i].clear();
                st[i]=0;
            }
            memset(ans,0,sizeof ans);
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            for(i=1;i<=m;i++){
                scanf("%d%d%lld",&s[i].a,&s[i].b,&s[i].v);
                if(s[i].a>s[i].b)
                    swap(s[i].a,s[i].b);
            }
            sort(s+1,s+1+m);
            cnt=0;
            int j;
            for(i=1;i<=m;i=j){
                for(j=i+1;j<=m;j++){
                    if(s[i].a==s[j].a&&s[i].b==s[j].b){
                        s[i].v+=s[j].v;
                    }
                    else
                        break;
                }
                s[++cnt]=s[i];
            }
            int block=sqrt(cnt);
            for(i=1;i<=cnt;i++){
                int x=s[i].a,y=s[i].b;
                in[x]++;
                in[y]++;
            }
            for(i=1;i<=n;i++){
                if(in[i]>block)
                    st[i]=1;
            }
            for(i=1;i<=cnt;i++){
                int x=s[i].a,y=s[i].b;
                if(st[x]){
                    sum[x][a[y]]+=s[i].v;
                }
                if(st[y]){
                    sum[y][a[x]]+=s[i].v;
                }
                ans[a[x]+a[y]]+=s[i].v;
            }
            for(i=1;i<=cnt;i++){
                int x=s[i].a,y=s[i].b;
                if(st[x]){
                    if(st[y]){
                        g[x].push_back(Edge{y,s[i].v});
                        g[y].push_back(Edge{x,s[i].v});
                    }
                    else{
                        g[y].push_back(Edge{x,s[i].v});
                    }
                }
                else{
                    if(st[y]){
                        g[x].push_back(Edge{y,s[i].v});
                    }
                    else{
                        g[x].push_back(Edge{y,s[i].v});
                        g[y].push_back(Edge{x,s[i].v});
                    }
                }
            }
            int q;
            printf("Case %d:
    ",++h);
            cin>>q;
            char as[10];
            while(q--){
                scanf("%s",as);
                if(as[0]=='A'){
                    int x,y;
                    scanf("%d%d",&x,&y);
                    printf("%lld
    ",ans[x+y]);
                }
                else{
                    int x;
                    scanf("%d",&x);
                    a[x]^=1;
                    if(st[x]){
                        for(i=0;i<=1;i++){
                            ans[(a[x]^1)+i]-=sum[x][i];
                            ans[a[x]+i]+=sum[x][i];
                        }
                        for(i=0;i<g[x].size();i++){
                            int j=g[x][i].u;
                            ll h=g[x][i].v;
                            sum[j][a[x]]+=h;
                            sum[j][a[x]^1]-=h;
                        }
                    }
                    else{
                        for(i=0;i<g[x].size();i++){
                            int j=g[x][i].u;
                            ll h=g[x][i].v;
                            ans[(a[x]^1)+a[j]]-=h;
                            ans[a[x]+a[j]]+=h;
                            if(st[j]){
                                sum[j][a[x]]+=h;
                                sum[j][a[x]^1]-=h;
                            }
                        }
                    }
                }
            }
        }
    }
    View Code
  • 相关阅读:
    Pentest_Mind-mapping 渗透测试思维导图
    pt-archiver归档数据丢失
    Vue笔记:bin-code-editor使用
    Vue笔记:Vue3 Table导出为Excel
    Go异步check简单示例
    flask_apscheduler定时任务组件使用
    组织沟通文化的变革与卓有成效的管理沟通
    业绩核能
    管理
    SAP MM 移动平均价管理的物料库存初始化导入的一个小问题
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12575481.html
Copyright © 2011-2022 走看看