Miraclys

一言(ヒトコト)

洛谷P2294 [HNOI2005]狡猾的商人

\(\large{题目链接}\)
\(\\\)
\(\Large\textbf{Solution: } \large{1.因为每次提供的是一段时间的利润,具体的每个月并不清楚,所以考虑直接判断前缀和是否合法即可。\\2.可以考虑带权并查集,设\text{top[x] = pre[find(x)] - pre[x]},然后每次操作如果在一个集合里,就直接判断是否合法,如果不在,那就更新\text{top}值。}\)
\(\\\)
\(\Large\textbf{Summary: } \large{像这种判断是否合法或者两者之间关系的题目,可以往图上想一想。}\)
\(\\\)
\(\Large\textbf{Code: }\)

#include <bits/stdc++.h>
#define gc() getchar() 
#define LL long long
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int N = 105;
const int M = 1005;
const int inf = 0x7fffffff;
int w, n, m, cnt, head[N], vis[N], r[N], dis[N];

struct Edge {
	int to, next, val;
}e[M << 1];

inline int read() {
	int x = 0, flg = 1;
	char ch = gc();
	while (!isdigit(ch)) {
		if (ch == '-') flg = -1;
		ch = gc();
	}
	while (isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
	return x * flg; 
}

inline void add(int x, int y, int w) {
	e[++cnt].to = y;
	e[cnt].val = w;
	e[cnt].next = head[x];
	head[x] = cnt;
}

inline bool Spfa() {
	queue <int> q;
	memset(vis, 0, sizeof (vis));
	rep(i, 0, n) dis[i] = inf;
	dis[0] = 0; vis[0] = 1; q.push(0);
	while (!q.empty()) {
		int x = q.front(); q.pop();
		vis[x] = 0;
		for (int i = head[x]; i ; i = e[i].next) {
			int u = e[i].to;
			if (dis[u] == inf) {
				dis[u] = dis[x] + e[i].val;
				if (!vis[u]) vis[u] = 1, q.push(u);
			}
			else if (dis[u] != dis[x] + e[i].val) return false;
		}
	}
	return true;
}

int main() {
	w = read();
	while (w--) {
		cnt = 0;
		memset(head, 0, sizeof (head));
		n = read(), m = read();
		int x, y, w;
		while (m--) x = read(), y = read(), w = read(), add(x - 1, y, w), add(y, x - 1, -w);
		int flg = Spfa();
		flg ? puts("true") : puts("false");
	}
	return 0;
} 

\(\\\)
\(\Large\textbf{Code: }\)

#include <bits/stdc++.h>
using namespace std;

const int N = 105;

int t, n, m, f[N], top[N];

inline int read() {
	int x = 0, flg = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-') flg = -1;
		ch = getchar();
	}
	while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
	return x * flg; 
}

inline void init() { for (int i = 0; i <= n; ++i) f[i] = i, top[i] = 0; }

inline int find(int x) {
	if (x == f[x]) return x;
	int temp = find(f[x]);
	top[x] += top[f[x]];
	return f[x] = temp;
}

int main() {
	t = read();
	while (t--) {
		n = read(), m = read();
		init(); int x, y, w, flg = 0;
		while (m--) {
			x = read() - 1, y = read(), w = read();
			int X = find(x), Y = find(y);
			if (X != Y) {
				top[X] = top[y] - top[x] - w;//top[X] = pre[Y] - pre[X], pre[Y] - pre[y] = top[y], pre[y] = pre[x] + w, top[x] = pre[X] - pre[x]
				f[X] = Y;
			} else if (top[y] - top[x] != w) { flg = 1; break; }
		}
		flg ? puts("false") : puts("true");
	}
	return 0;
} 
posted @ 2020-03-27 22:50  Miraclys  阅读(113)  评论(0编辑  收藏  举报

关于本博客样式

部分创意和图片借鉴了

BNDong

的博客,在此感谢