zoukankan      html  css  js  c++  java
  • HDU 3038 How Many Answers Are Wrong 很有意思的一道并查集问题

    题目大意:TT 和 FF玩游戏(名字就值五毛),有一个数列,数列有N个元素,现在给出一系列个区间和该区间内各个元素的和,如果后出现的一行数据和前面一出现的数据有矛盾,则记录下来。求有矛盾数据的数量。

    题目思路:刚刚拿到手时一脸懵逼,这是并查集?后来发现还真是并查集 - -!!

    如果数据有错那么会是什么情况?

    1-10 10

    1-5   5

    6-10  4

    很明显第三行的数据和已知的数据产生了矛盾,我们分析一下矛盾是如何产生的。

    我们用v[i]来统计最右端为i的区间和,那么:

    第一行数据得知v[10]=10;

    第二行数据得知v[5]=5;

    第三行数据在与第二行数据合并时发现 V[10]=9.

    这样矛盾便产生了。

    由于存在集合划分的问题,所以我们理应想到并查集去解决问题。具体问题看代码吧,代码我觉得解释的比较详细了

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #define INF 0x3f3f3f3f
    #define MAX 1000005
    
    using namespace std;
    
    int father[MAX],v[MAX],n,m;
    
    int Find(int x)
    {
        if(father[x]==-1)
            return x;
        int k=Find(father[x]);
    
        v[x]+=v[father[x]];//对v[x]进行更新
    
        return father[x]=k;
    }
    
    int main()
    {
        int i,j,a,b,c;
    
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            int ans=0;
            for(i=0;i<MAX;i++)
            {
                father[i]=-1;
                v[i]=0;
            }
    
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                
                a--;//为什么要减一?你知道了区间1-5,和6-10的和,如果你不把6减1,你如何经行下面的更新呢?
    
                int x=Find(a);
                int y=Find(b);
    
                if(x!=y)//如果发现两个根节点不相同,则经行更新
                {
                    father[y]=x;
    
                    v[y]=v[a]-v[b]+c;//由式子:v[y]=v[a]-(v[b]-c),化简而得,自己可以画个图推一下,并不难。
                }
    
                else//如果根节点相同了,我们就可以经行判断了
                {
                    if(v[b]-v[a] !=c)//v[b]-v[a]根据之前的条件得到的区间a-b的和,如果这个值并不等于C证明与前面矛盾。
                        ans++;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    vue 组件复用不刷新
    ES6删除对象中的某个元素
    UI组件--element-ui--Table组件自定义合计行
    UI组件--element-ui合计行在横向滚动条下面的解决方法
    java笔记 -- 数组
    java笔记 -- 输入输出
    java笔记 -- java字符串
    java笔记 -- 数学函数与常量
    java笔记 -- java运算
    java笔记 -- java变量与常量的声明
  • 原文地址:https://www.cnblogs.com/alan-W/p/5746472.html
Copyright © 2011-2022 走看看