Solution
前言:相比于前向星,我更喜欢vector,码量更小。
根据题目意思,构建一个无向图,无向图的花费部分需要记录两个变量,一个是自己的x,一个是终点的y。这里要记得换起点要换x和y。
那么这里把深度优先搜索遍历全部节点,把从未遍历过的节点定义成1.0,其余节点去根据x,y去确定第一次来到的点的值,如果第二次遍历到这个点,就要去判断向前的值是否满足当前的终点,如果不满足flag=true。
#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;
inline int read() {
int s = 0, w = 1; char ch = getchar();
while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
return s * w;
}
const int N = 1e4 + 7;
const double eps = 1e-3;
struct Node {
int v;
int wx, wy;
};
vector<Node> e[N];
bool vis[N], flag;
double w[N];
int n, m;
void dfs(int u, int fa) {
vis[u] = 1;
for (auto it : e[u]) {
if (it.v != fa) {
if (vis[it.v]) {
if (abs(w[it.v] - w[u] * it.wy / it.wx) <= eps)
continue;
else {
flag = true;
return;
}
}
else {
w[it.v] = w[u] * it.wy / it.wx;
dfs(it.v, u);
}
}
}
}
int main() {
int T = read();
for (int ca = 1; ca <= T; ++ca) {
flag = false;
n = read(), m = read();
memset(vis, 0, sizeof(vis));
for (int i = 0; i <= n; ++i) e[i].clear();
for (int i = 1; i <= m; ++i) {
int u = read(), v = read(), x = read(), y = read();
e[u].push_back({ v,x,y });
e[v].push_back({ u,y,x }); //注意更换x,y
}
for (int i = 1; i <= n; ++i) {
if (!vis[i]) {
w[i] = 1.0;
dfs(i, 0);
}
if (flag) break;
}
if (flag)
printf("Case #%d: No\n", ca);
else
printf("Case #%d: Yes\n", ca);
}
return 0;
} 
京公网安备 11010502036488号