[kuangbin帶你飛]專題五 並查集---hdu--3038(帶權並查集入門)

How Many Answers Are Wrong(HDU3038)

vj題目地址

轉載自,(我這裏只放了一道題,原博主放了幾道題)

題意:

在這裏插入圖片描述
在這裏插入圖片描述

思路:

1.由於有很多對點的關係,建立帶權並查集
2. 建立以左端點爲子,右端點爲祖先的帶權並查集。
3. 由圖中可知,當[1,4]確定和[3,4]確定時,添加[1,3]就可能會發生logic錯誤了。

在這裏插入圖片描述

1) 而從[1,2]很難轉換到去求[1,4]-[3,4].所以這裏有個小技巧,取開區間左端點,轉換爲求(0,2]=(0,4]-(2,4]的值
在這裏插入圖片描述
2) 又通過觀察可得,當區間爲(0,3](紅線)時由於3爲祖先,不在0,4,2這個並查集內,所以不考慮,那什麼時候考慮呢??
綠線:當兩個區間的,左和右端點是同一個並查集時。

在這裏插入圖片描述

反思:

  1. 帶權並查集的模板
int find(int x)
{
    if(x==f[x])return x;
    int root=find(f[x]);
    dis[x]+=dis[f[x]];
    return f[x]=root;
}
  1. 合併時的代碼。
	int A=find(a),B=find(b);
	f[A]=B;
        dis[A]=dis[b]-dis[a]+s;
  1. 區間的操作時(涉及向量,並查集)可以把某一端點變爲開區間。

AC

#include <iostream>
#include <cstdio>
#include <cmath>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int a[maxn],f[maxn];
ll dis[maxn];
int find(int x)
{
    if(x==f[x])return x;
    int root=find(f[x]);
    dis[x]+=dis[f[x]];
    return f[x]=root;
}
int main()
{
    int n,m;
    while(~scanf("%d%d", &n,&m))
    {
        For(i,0,n)dis[i]=0,f[i]=i;
        int ans=0;
        For(i,1,m)
        {
            int a,b;
            ll s;
            scanf("%d%d%lld", &a, &b, &s);
            a--;
            int A=find(a),B=find(b);
            //cout<<dis[a]<<' '<<dis[b]<<endl;
            //find(a-1),find(b+1);
            //cout<<dis[a-1]<<' '<<dis[b+1]<<endl;
           // if(dis[b+1])cout<<"ok"<<endl;
           //cout<<(dis[a-1]||dis[b+1])<<endl;
           if(A==B)
           {
               if(abs(dis[b]-dis[a])!=s)ans++;
           }
            else if(A!=B)
            {
                //if(dis[a-1]||dis[b+1])
                //{
                    //cout<<abs(dis[b+1]-dis[a-1])<<endl;
                    //if(s!=abs(dis[b+1]-dis[a-1])){ans++;continue;}
                //}
                f[A]=B;
                dis[A]=dis[b]-dis[a]+s;
               // cout<<dis[A]<<' '<<A<<endl;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章