zoukankan      html  css  js  c++  java
  • hdoj3038(带权并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038

    题意:对于给定的a1..an,通过询问下标x..y,给出a[x]+...+a[y],但给出的值可能是错的,需要判断,因为题目说的是整数,也可能是负整数,所以逻辑错误只有一种情况:给了a..c的值x,a..b的值y,之后又给了b..c的值z,若x!=y+z,则是错误答案,否则是正确答案。

    思路:

    参考巨巨的博客:https://www.cnblogs.com/liyinggang/p/5327055.html。

    用root数组表示祖先,dis数组表示到祖先的距离(如对于数据1 2 3,3的祖先为1,则dis[3]=1+2=3),都需要初始化。

    每次询问输入a,b,s,同时--b,ra=getr(a),rb=getr(b)。

    1.ra!=rb:则合并

    令root[rb]=ra,dis[rb]=dis[a]+s-dis[b](画图模拟一下,记住此处的b加一了)

    2.ra==rb:则查询

    若dis[b]-dis[a]!=s,则为错误答案。

    最后注意这道题是多组数据输入,详见代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn=200005;
     5 int n,m,a,b,s,res;
     6 int root[maxn],dis[maxn];
     7 
     8 int getr(int k){
     9     if(root[k]==k) return k;
    10     else{
    11         int tmp=root[k];
    12         root[k]=getr(root[k]);
    13         dis[k]+=dis[tmp];
    14         return root[k];
    15     }
    16 }
    17 
    18 int main(){
    19     while(~scanf("%d%d",&n,&m)){
    20         res=0;
    21         for(int i=1;i<=n+1;++i)
    22             root[i]=i,dis[i]=0;
    23         while(m--){
    24             scanf("%d%d%d",&a,&b,&s);
    25             ++b;
    26             int ra=getr(a),rb=getr(b);
    27             if(ra==rb){
    28                 if(dis[b]-dis[a]!=s)
    29                     ++res;
    30             }
    31             else{
    32                 root[rb]=ra;
    33                 dis[rb]=dis[a]+s-dis[b];
    34             }
    35         }
    36         printf("%d
    ",res);
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    2015年蓝桥杯省赛A组c++第3题
    2015年蓝桥杯省赛A组c++第1题
    算法学竞赛常用头文件模板
    Android+Tomcat通过http获取本机服务器资源
    Ubuntu16.04LTS卸载软件的命令
    20个有趣的Linux命令
    Ubuntu16.04开机蓝屏问题解决
    Ubuntu启动时a start job is running for dev-disk-by延时解决
    Cookie与Session
    JS 闭包
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10454754.html
Copyright © 2011-2022 走看看