zoukankan      html  css  js  c++  java
  • 【BZOJ】1202: [HNOI2005]狡猾的商人

    【题意】w组数据,给定n和m,给出m段区间[s,t](1<=s<=t<=n)的数字和,求是否矛盾。n<100,m<1000,w<100。

    【算法】带权并查集

    【题解】由于存在负数,唯一判断信息合法性的途径只有多个已知区间能组成一个已知大区间。

    假设有n+1个点0~n表示sum[0]~sum[n],对这些点维护带权并查集,令d[x]表示sum[x]-sum[fa[x]]。

    一个已知区间实际上是sum[t] - sum[s-1],如果s-1和t不属于同一个集合就并起来,并且更新d。(注意前缀和方向)

    如果属于同一个集合就可以判断是否合法。

    最后要注意find过程的执行顺序:int t=find(fa[x]); d[x]+=d[fa[x]]; fa[x]=t;

    复杂度O(w*m)。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=110;
    int fa[maxn],d[maxn];
    int n,m,T;
    int find(int x){
        if(fa[x]==x)return x;
        int t=find(fa[x]);
        d[x]+=d[fa[x]];
        fa[x]=t;
        return fa[x];
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            memset(d,0,sizeof(d));
            scanf("%d%d",&n,&m);
            for(int i=0;i<=n;i++)fa[i]=i;
            bool flag=0;
            for(int i=1;i<=m;i++){
                int x,y,w;
                scanf("%d%d%d",&x,&y,&w);
                x--;
                int p=find(x),q=find(y);
                if(p!=q){
                    fa[q]=p;
                    d[q]=d[x]+w-d[y];
                }
                else if(d[y]-d[x]!=w){flag=1;break;}
            }
            if(flag)printf("false
    ");else printf("true
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    unable to retrieve container logs for docker kubernetes
    Restart container within pod
    Kubernetes1.3:POD生命周期管理
    Options of the DB storage of prometheus
    prometheus重启hang住问题记录
    prometheus交流资源
    nc 从服务器上传下载文件
    负载均衡监控需求
    prometheus消耗内存问题
    10.Docker 镜像使用
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6234769.html
Copyright © 2011-2022 走看看