zoukankan      html  css  js  c++  java
  • hdu3047 Zjnu Stadium【带权并查集】

    <题目链接>

    <转载于 >>> >

    题目大意:

    有n个人坐在zjnu体育馆里面,然后给出m个他们之间的距离, A B X, 代表B的座位比A多X. 然后求出这m个关系之间有多少个错误,所谓错误就是当前这个关系与之前的有冲突。

    解题分析:

    (1)弄清题意,找出出现冲突的位置,判断冲突很简单就是当两个人在同一行坐,同时他们到根节点的距离差值正好是他们之间的差值,此时就出现了冲突了。

    (2)关键有两个地方,这也是并查集题目的难点,就是压缩集合,和求节点到根的距离。这里压缩集合就很简单了,一个通用的递归。求到跟的距离dist[a] += dist[tem]; dist[rb]=dist[a]+x-dist[b];注意这两行代码,这是核心代码,首先第一行是求出节点a到根的距离。第二行代码使用的是数学中向量计算的原理如图

    注意x是指b->a 

    这道题我还是很不明白,为什么连

    3 2

    1 2 150

    2 3 150

    这组数据输出的都是0,我觉得应该是1.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int maxn=5e4+10;
    int n,m,ans;
    
    int fa[maxn];
    int r[maxn];
    
    int find(int x){
        if(fa[x]==x)return x;
        int temp=fa[x];
        fa[x]=find(fa[x]);
        r[x]=(r[x]+r[temp])%300;
        return fa[x];
    }
    
    void Uion(int a,int b,int c){
        int ra=find(a);
        int rb=find(b);
        if(ra==rb){
            if((r[a]-r[b]+300)%300!=c)ans++;      //这里意味着原来所确定a、b之间的关系与现在a、b给定的关系发生冲突,所以ans++
        }
        else{
            fa[ra]=rb;
            r[ra]=(c-r[a]+r[b]+300)%300;          //矢量求解ra到rb的距离
        }
    }
    
    int main(){
        while(scanf("%d %d",&n,&m)!=EOF){   
            for(int i=1;i<=n;i++){
                fa[i]=i;
                r[i]=0;
            }
            ans=0;
            for(int i=1;i<=m;i++){
                int a,b,c;
                scanf("%d %d %d",&a,&b,&c);
                Uion(a,b,c);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

    2018-08-14

  • 相关阅读:
    JAVA队列的使用
    四种线程池的使用
    JAVA中只有值传递
    为什么说Java语言是平台无关的?
    Jsoup爬虫解析
    java爬虫
    oracle触发器
    easyUi引入方法
    highchart
    July 20th 2017 Week 29th Thursday
  • 原文地址:https://www.cnblogs.com/00isok/p/9478123.html
Copyright © 2011-2022 走看看