带权并查集分析Java(hdu-3038 & poj1182)

HDU-3038

在这里插入图片描述
根据这个规则构成带有权值的树

import java.util.Scanner;

public class Main_HDU3038 {
	static int[] p = new int[200005];
	static int[] d = new int[200005];  //表示的是i到根节点的权值
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()) {
			int n = sc.nextInt();
			int m = sc.nextInt();
			for(int i=0;i<=n;i++) {
				p[i] = i;
				d[i] = 0;
			}
			int ans = 0;
			for(int i=1;i<=m;i++) {
				int a = sc.nextInt();
				int b = sc.nextInt();
				int s = sc.nextInt();
				int fa = find(--a);
				int fb = find(b);
				if(fa==fb&&d[b]-d[a]!=s) {
					ans++;
					continue;
				}else if(fa!=fb){  
					p[fb] = fa;
					d[fb] = d[a]+s-d[b];  //不同的父节点,求其中一个父节点到根节点之和
				}
			}
			System.out.println(ans);			
		}

	}
	public static int find(int x) {
		if(x==p[x]) return x;
		int rt = find(p[x]);
		d[x] += d[p[x]];  //更新权值
		p[x] = rt;
		return p[x];
	}
}

POJ-1182

在这里插入图片描述

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main_POJ1182 {
	static int[] pre = new int[50005];
	static int[] r = new int[50005];  //表示i的权值(i与pre[i]的关系 ) 0代表同类1代表吃父节点2代表吃子节点
	public static void main(String[] args) {
		InputReader1182 sc = new InputReader1182();
		int n = sc.nextInt();
		int k = sc.nextInt();
		for(int i=0;i<=n;i++) {
			pre[i] = i;
			r[i] = 0;
		}
		int ans=0;
		for(int i=1;i<=k;i++) {
			int d = sc.nextInt();
			int x = sc.nextInt();
			int y = sc.nextInt();
			if(x>n||y>n||(d==2&&x==y)) {
				ans++;
				continue;
			}
			int fx = find(x);
			int fy = find(y);
			if(fx==fy&&(r[x]-r[y]+3)%3!=d-1)
				ans++;
			else if(fx!=fy){
				pre[fx] = fy;
				r[fx] = (r[y]-r[x]+3+d-1)%3;  //两个不相同的父节点建立关系通过向量法
			}
		}
		System.out.println(ans);
	}
	public static int find(int x) {
		if(x==pre[x]) return x;
		int rt = pre[x];
		pre[x] = find(pre[x]);
		r[x] = (r[x]+r[rt])%3;
		return pre[x];
	}
}	
class InputReader1182
{
    BufferedReader buf;
    StringTokenizer tok;
    InputReader1182()
    {
        buf = new BufferedReader(new InputStreamReader(System.in));
    }
    boolean hasNext()
    {
        while(tok == null || !tok.hasMoreElements()) 
        {
            try
            {
                tok = new StringTokenizer(buf.readLine());
            } 
            catch(Exception e) 
            {
                return false;
            }
        }
        return true;
    }
    String next()
    {
        if(hasNext()) return tok.nextToken();
        return null;
    }
    int nextInt()
    {
        return Integer.parseInt(next());
    }
}

推荐很好的博客:
带权并查集介绍

发布了2 篇原创文章 · 获赞 3 · 访问量 148

猜你喜欢

转载自blog.csdn.net/weixin_45948204/article/details/104616432