P1955 [NOI2015]程序自动分析 并查集 离散化
给定n个规则
每个规则 x y z
z = 1表示 ax = ay ,z = 0 表示 ax ≠ ay 。
若最后是矛盾的输出NO,否则YES
初开题面是裸的并查集。
再看体面发现 x y的范围 1e9,而n只有1e6,就是说虽然xy很大但是数最多只有1e6个,考虑离散化。
离散化套路:排序,unqiue,lower_bound。
这里数组没有开2倍wa了很久
#pragma warning(disable:4996) #include<iostream> #include<algorithm> #include<bitset> #include<tuple> #include<unordered_map> #include<fstream> #include<iomanip> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<list> #include<queue> #include<stack> #include<sstream> #include<cstdio> #include<ctime> #include<cstdlib> #define pb push_back #define INF 0x3f3f3f3f #define inf 0x7FFFFFFF #define moD 1000000003 #define pii pair<int,int> #define eps 1e-8 #define equals(a,b) (fabs(a-b)<eps) #define bug puts("bug") #define re register #define fi first #define se second typedef long long ll; typedef unsigned long long ull; const ll MOD = 998244353; const int maxn = 1e6 +5; const double Inf = 10000.0; const double PI = acos(-1.0); using namespace std; ll mul(ll a, ll b, ll m) { ll res = 0; while (b) { if (b & 1) res = (res + a) % m; a = (a + a) % m; b >>= 1; } return res % m; } ll quickPower(ll a, ll b, ll m) { ll base = a; ll ans = 1ll; while (b) { if (b & 1) ans = mul(ans, base , m); base = mul(base, base , m); b >>= 1; } return ans; } int readint() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } ll readll() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } void Put(ull x) { if (x > 9) Put(x / 10); putchar(x % 10 + '0'); } int pre[2 * maxn]; vector<tuple<int,int,int> > p; vector<int> a; int Find(int x) { return pre[x] != x ? pre[x] = Find(pre[x]) : x; } void Union(int x, int y) { int p = Find(x); int q = Find(y); if (p != q) pre[q] = p; } int main() { int n; int x, y; int e; int T = readint(); while (T--) { n = readint(); a.clear(); p.clear(); memset(pre, 0, sizeof pre); for (int i = 0; i < n; i++) { x = readint(), y = readint(); e = readint(); a.push_back(x), a.push_back(y); p.emplace_back(x, y, e); } sort(a.begin(), a.end()); int len = unique(a.begin(), a.end()) - a.begin(); for (int i = 1; i <= 2 * len; i++) pre[i] = i; for (int i = 0; i < n; i++) { if (get<2>(p[i]) == 1) { int xx = lower_bound(a.begin(), a.begin() + len, get<0>(p[i])) - a.begin() + 1; int yy = lower_bound(a.begin(), a.begin() + len, get<1>(p[i])) - a.begin() + 1; if (Find(xx) != Find(yy)) Union(xx, yy); } } int f = 1; for (int i = 0; i < n; i++) { if (!get<2>(p[i])) { int xx = lower_bound(a.begin(), a.begin() + len, get<0>(p[i])) - a.begin() + 1; int yy = lower_bound(a.begin(), a.begin() + len, get<1>(p[i])) - a.begin() + 1; if (Find(xx) == Find(yy)) { f = 0; break; } } } if (f) puts("YES"); else puts("NO"); } }