小诚因为金铲铲D不到牌破产啦
小诚因为金铲铲D不到牌破产啦
问题描述
小诚和他身边的朋友最近好像出了点经济问题……
已知小诚的人际关系网中包含
众所周知,欠钱容易借钱难,没借到之前是孙子,借到了之后对面是孙子。所以两个人之间,如果不是关系密切的朋友,就无法放心地互相借钱,小诚通过摸索,知道了他们之间有
请问所有的人能够通过互相借钱满足他们的需求吗?
注意,有的人可能一开始就是负债的状态,即
输入
- 第一行两个整数
分别表示人数和关系密切的朋友对数。 - 接下来一行
个整数 ,表示每个人手上初始有的钱。 - 接下来一行
个整数 ,表示每个人手上最后希望恰好有的钱。 - 接下来
行,每行两个整数 ,表示 和 是关系密切的朋友。
约束条件
输出
对于每一组数据,输出一行一个字符串,如果可以满足,输出 "Yes",否则输出 "No"。
示例
输入样例 1
3 2
1 2 3
2 2 2
1 2
2 3
输出样例 1
Yes
题解
仅需将每组朋友 共有的初始有的钱 和 共有的最后希望恰好有的钱 进行对比即可
#include<iostream>
using namespace std;
const int MAXN = 2e5 + 10;
int par[MAXN];
long long sumA[MAXN], sumB[MAXN], a[MAXN], b[MAXN];
int find(int x);
void unionSets(int x, int y);
int main() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
par[i] = i;
}
for (int i = 1; i <= n; ++i) {
scanf("%lld", &b[i]);
}
for (int i = 1; i <= m; ++i) {
int x, y;
scanf("%d %d", &x, &y);
unionSets(x, y);
}
for (int i = 1; i <= n; ++i) {
int root = find(i);
sumA[root] += a[i];
sumB[root] += b[i];
}
for (int i = 1; i <= n; ++i) {
if (par[i] == i) {
if (sumA[i] != sumB[i]) {
printf("No\n");
return 0;
}
}
}
printf("Yes\n");
return 0;
}
int find(int x) {
return par[x] == x? x : find(par[x]);
}
void unionSets(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
par[rootY] = rootX;
}
}