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; }