D - 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<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 100007;
int f[maxn],d[maxn];
int n,m,l,r,v;
int find(int x)
{
if(x==f[x])return x;
int now = f[x];
f[x]=find(f[x]);
d[x]=d[x]+d[now];
return f[x];
}
int main()
{
scanf("%d %d",&n,&m);
int ok = 1;
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&l,&r,&v);
int fl = find(l);
int fr = find(r);
if(fl==fr)
{
if(d[l]-d[r]!=v)ok = 0;
}
else
{
f[fl]=fr;
d[fl]=v+d[r]-d[l];
}
}
if(ok)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}