HDU——3038 How Many Answers Are Wrong (with the right to check and collect)

Link to the original question: http://acm.hdu.edu.cn/showproblem.php?pid=3038


Insert picture description here
Test sample

Sample Input
10 5
1 10 100
7 10 28
1 3 32
4 6 41
6 6 1
Sample Output
1

Question: There is a length of nnUnknown integer sequence of n , now gives yoummThe m interval sum information requires you to find the number of error messages.

Problem-solving idea: This inscription is really difficult to understand literally. What is the basis for the error? How do we express the interval sum? Does the prefix sum? Let us first explain the basis of the error:The original question stated that as long as the information does not conflict with the previous information, the information will be considered correct, and if it conflicts, it will be wrong.So can we use prefix sum to solve it? It may be more troublesome, and I don’t even know how to operate. Here we can use the right and check to solve the problem. Here is a guide to an article with the right and check to explain the blog: and check to learn and organize . The information given each time is the left end of the interval, the right end of the interval and the sum of the interval. That is, we can combine the left end of the interval and the right end of the interval, and represent their weights as an interval sum. Here is a detail to pay attention to, that is, if we want to express an interval sum, then we either open left and closed right, or left closed and right open, so the method of obtaining the interval is also different.That is, if [b, c), [a, c) (b,c),(a,c)[b,c),[a,c ) . If the root nodeccc , thenbbWhat b represents is the interval[b, c) [b, c)[b,c ) and thenccc represents the interval[a, c) (a, c)[a,c ) sum. So we have to get[a, b] [a, b][a,The interval sum of b ] is naturallyvalue [a] − value [b] value[a]-value[b]value[a]value[b]This is why we have to set up such an interval notation. OK, look at the code specifically.

AC code

/*
*邮箱:[email protected]
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>	//POJ不支持

#define rep(i,a,n) for (int i=a;i<=n;i++)//i为循环变量,a为初始值,n为界限值,递增
#define per(i,a,n) for (int i=a;i>=n;i--)//i为循环变量, a为初始值,n为界限值,递减。
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
#define fi first
#define se second
#define mp make_pair

using namespace std;

const int inf = 0x3f3f3f3f;//无穷大
const int maxn = 2e5+3;//最大值。
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll>  pll;
typedef pair<int, int> pii;
//*******************************分割线,以上为自定义代码模板***************************************//

int n,m;
int value[maxn];
int father[maxn];
int Find(int x){
    
    
	//这里要使用递归去更新带权值。
	if(x==father[x]){
    
    
		return x;
	}
	else{
    
    
		int temp=father[x];
		father[x]=Find(father[x]);//继续递归下去找到根节点,再回溯更新带权值。
		value[x]+=value[temp];
		return father[x];//返回根节点。
	}
}
int main(){
    
    
	//freopen("in.txt", "r", stdin);//提交的时候要注释掉
	IOS;
	while(cin>>n>>m){
    
    
		rep(i,1,n+1){
    
    
			//初始化,一开始根节点就为自己,那么到根节点的距离也自然为0。
			value[i]=0;
			father[i]=i;
		}
		int cnt=0;
		int x,y,d;
		rep(i,1,m){
    
    
			cin>>x>>y>>d;
			//我们定义区间需要左开右闭。
			y++;
			int fx=Find(x);
			int fy=Find(y);
			if(fx!=fy){
    
    
				//说明不冲突,我们进行合并。
				father[fx]=fy; //将编号较大的节点作为父节点。
				value[fx]=-value[x]+value[y]+d;
			}
			else{
    
    
				if(value[x]-value[y]!=d){
    
    
					cnt++;
				}
			}
		}
		cout<<cnt<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/hzf0701/article/details/109004378