zoukankan      html  css  js  c++  java
  • HDU 3047 Zjnu Stadium 带权并查集

    题目来源:HDU 3047 Zjnu Stadium

    题意:给你一些人 然后每次输入a b c 表示b在距离a的右边c处 求有多少个矛盾的情况

     思路:用sum[a] 代表a点距离根的距离 每次合并时假设根一样 推断sum数组是否符合情况 根不一样 合并两棵树 这里就是带权并查集的精髓

    sum[y] = sum[a]-sum[b]+x 这里y的没有合并前b的根 

    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 50010;
    int f[maxn], flag[maxn], sum[maxn];
    int cnt;
    
    void init(int n)
    {
    	for(int i = 1; i <= n; i++)
    		f[i] = i;
    	//memset(rank, 0, sizeof(rank));
    	memset(sum, 0, sizeof(sum));
    }
    
    int find(int x)
    {
    	if(x != f[x])
    	{
    		int rt = find(f[x]);
    		sum[x] += sum[f[x]];
    		f[x] = rt;
    		return rt;
    	}
    	return f[x];
    }
    
    void merge(int i, int j)
    {
    	
    	int x = find(i);
    	int y = find(j);
    	if(x != y)
    	{
    		f[y] = x;
    	}
    }
    
    int main()
    {
    	int n, m;
    	while(scanf("%d %d", &n, &m) != EOF)
    	{	
    		init(n);
    		int ans = 0;
    		while(m--)
    		{
    			int w, u, v;
    			scanf("%d %d %d", &u, &v, &w);
    			int x = find(u);
    			int y = find(v);
    			if(x != y)
    			{
    				f[y] = x;
    				sum[y] = sum[u] - sum[v] + w;
    			}
    			else
    			{
    				int sum1 = sum[u];
    				int sum2 = sum[v];
    				if(sum2-sum1 != w)
    					ans++;
    			}
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }


  • 相关阅读:
    课后作业03
    课堂测验02
    构建之法阅读笔记02
    进度条 二
    软件工程个人作业02
    Sprint6
    Sprint5
    Alpha版总结会议
    Beta版总结会议
    Alpha阶段项目Postmortem会议总结
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5352618.html
Copyright © 2011-2022 走看看