2021-1-21 并查集

2020-1-21 并查集

How Many Answers Are Wrong(带权并查集)

TT and FF are … friends. Uh… very very good friends -________-b

FF is a bad boy, he is always wooing TT to play the following game with him. This is a very humdrum game. To begin with, TT should write down a sequence of integers-_-!!(bored).

Then, FF can choose a continuous subsequence from it(for example the subsequence from the third to the fifth integer inclusively). After that, FF will ask TT what the sum of the subsequence he chose is. The next, TT will answer FF’s question. Then, FF can redo this process. In the end, FF must work out the entire sequence of integers.

BoringBoringa very very boring game!!! TT doesn’t want to play with FF at all. To punish FF, she often tells FF the wrong answers on purpose.

The bad boy is not a fool man. FF detects some answers are incompatible. Of course, these contradictions make it difficult to calculate the sequence.

However, TT is a nice and lovely girl. She doesn’t have the heart to be hard on FF. To save time, she guarantees that the answers are all right if there is no logical mistakes indeed.

What’s more, if FF finds an answer to be wrong, he will ignore it when judging next answers.

But there will be so many questions that poor FF can’t make sure whether the current answer is right or wrong in a moment. So he decides to write a program to help him with this matter. The program will receive a series of questions from FF together with the answers FF has received from TT. The aim of this program is to find how many answers are wrong. Only by ignoring the wrong answers can FF work out the entire sequence of integers. Poor FF has no time to do this job. And now he is asking for your help~(Why asking trouble for himself~~Bad boy)

Input

Line 1: Two integers, N and M (1 <= N <= 200000, 1 <= M <= 40000). Means TT wrote N integers and FF asked her M questions.

Line 2…M+1: Line i+1 contains three integer: Ai, Bi and Si. Means TT answered FF that the sum from Ai to Bi is Si. It’s guaranteed that 0 < Ai <= Bi <= N.

You can assume that any sum of subsequence is fit in 32-bit integer.

扫描二维码关注公众号,回复: 14650679 查看本文章

Output

A single line with a integer denotes how many answers are wrong.

Sample Input

10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1

Sample Output

1

大致题意:
对n个数进行m次查询,每次给出ai、bi、si三个数,代表从第ai到第bi个数的和为si,通过前后矛盾判断m次中谎言个数并输出。

方法:

#include<stdio.h>

#define maxn 200000+10
long long r[maxn],father[maxn];
//r储存当前位置到父节点的距离
//father储存父节点 

//下面是初始化函数
void mm(int x){
    
    
	father[x]=x;
	r[x]=0;
}

//下面是查找根节点和压缩路径的函数
long long find(long long i){
    
    
	long long t;
	if(father[i]!=i){
    
    //压缩路径
		t=find(father[i]);//寻找父节点的父节点(查找根节点
		r[i]=r[father[i]]+r[i];//将与父节点的距离用与根节点的距离迭代
		father[i]=t;//根节点迭代了父节点
	}
	return father[i];//返回根节点
}

int main(){
    
    
	int n,m;
	long long ai,bi,si,rootai,rootbi;
	while(~scanf("%d %d",&n,&m)){
    
    //不知道为什么要多组(题目好像没有要求
	//但是不多组就是错的
	int sum=0;//因为是多组,所以每次sum要记得清零
	for(int i=1;i<=n+1;i++)//n个数字 对应n+1个区域
	   mm(i);
	while(m--){
    
    
		scanf("%lld %lld %lld",&ai,&bi,&si);
		bi++;//ai-bi对应的区间是点ai后到点bi
		rootai=find(ai);rootbi=find(bi);//寻找ai、bi根节点
		if(rootai==rootbi){
    
    //根节点相同,可以比较
			if(si!=r[bi]-r[ai])sum++;
		}
		else{
    
    //根节点不同,连接同一根节点
			father[rootbi]=rootai;
			r[rootbi]=r[ai]-r[bi]+si;
		}
	} 
	 printf("%lld\n",sum); 
} }

并查集模板补充
1.find函数 基础查找根节点(无路径压缩)

int find(int x){
    
    
     int r=x;
     while(pre[r]!=r)
        r=pre[r];//不断寻找父节点,直到发现根节点
}

2.join函数 合并根节点

void join(int x,int y){
    
    
     int fx=find(x),fy=find(y);
     if(fx!=fy) pre[fx]=fy;//x、y也可互换
}

3.路径压缩

int find_pre(int x){
    
    
     if(pre[x]==x)
        return x;
     return pre[x]=find_pre(pre[x]);//递归
     //目的:将每个x的pre(父节点)变成根节点   
}

4.初始化

void m{
    
    
   pre[i]=i;
}

猜你喜欢

转载自blog.csdn.net/m0_52433146/article/details/112966772