People on a Line
Time limit : 2sec / Memory limit : 256MB
Score : 400 points
Problem Statement
There are N people standing on the x-axis. Let the coordinate of Person i be xi. For every i, xi is an integer between 0 and 109 (inclusive). It is possible that more than one person is standing at the same coordinate.
You will given M pieces of information regarding the positions of these people. The i-th piece of information has the form (Li,Ri,Di). This means that Person Ri is to the right of Person Li by Di units of distance, that is, xRi−xLi=Di holds.
It turns out that some of these M pieces of information may be incorrect. Determine if there exists a set of values (x1,x2,…,xN) that is consistent with the given pieces of information.
Constraints
- 1≤N≤100 000
- 0≤M≤200 000
- 1≤Li,Ri≤N (1≤i≤M)
- 0≤Di≤10 000 (1≤i≤M)
- Li≠Ri (1≤i≤M)
- If i≠j, then (Li,Ri)≠(Lj,Rj) and (Li,Ri)≠(Rj,Lj).
- Di are integers.
Input
Input is given from Standard Input in the following format:
N M L1 R1 D1 L2 R2 D2 : LM RM DM
Output
If there exists a set of values (x1,x2,…,xN) that
is consistent with all given pieces of information, print Yes
; if it does not
exist, print No
.
Sample Input 1
3 3 1 2 1 2 3 1 1 3 2
Sample Output 1
Yes
Some possible sets of values (x1,x2,x3) are (0,1,2) and (101,102,103).
Sample Input 2
3 3 1 2 1 2 3 1 1 3 5
Sample Output 2
No
If the first two pieces of information are correct, x3−x1=2 holds, which is contradictory to the last piece of information.
Sample Input 3
4 3 2 1 1 2 3 5 3 4 2
Sample Output 3
Yes
Sample Input 4
10 3 8 7 100 7 9 100 9 8 100
Sample Output 4
No
Sample Input 5
100 0
Sample Output 5
Yes
题目的意思是:给你多组数据每组三个数,分别是哪个点和哪个点之间的距离,问你是否有这样一组数满足所有的组数;
题目用并查集做,每加一组数据就进行一次查询和合并,二个数组,一个存每个点的祖先是谁,还有一个存的是这个点到祖先的距离;
#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include<cstring>
#define max(x,y) x>y?x:y
using namespace std;
const int maxn=1011111;
int f[maxn];
int d[maxn];
int find(int x)
{
if(f[x]==x)
return x;
int r=find(f[x]);
d[x]=d[f[x]]+d[x];//当前x到她老祖宗的距离等于他现在的距离加上她爸爸到老祖宗的距离
return f[x]=r; //把每个子节点合并到他的祖先
}
int fix(int x,int y,int z)
{
int fx=find(x);
int fy=find(y);
if(fx==fy)
return z==d[y]-d[x];
f[fy]=fx;//把x当作y的爸爸;
d[fy]=d[x]+z-d[y];
return 1;
}
int main()
{
int n,m;
int lose=1;
cin>>n>>m;
for(int i=1;i<=n;i++)//初始化:先把所有点的爸爸都设为自己;
f[i]=i;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
if(lose)
lose=fix(x,y,z);
}
if(lose)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
return 0;
}