^m
路漫漫

题意:给定n个(xi = xj) 或 (xi != xj) 的条件,问是否可能成立

BZOJ链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4195

luogu链接:https://www.luogu.org/problemnew/show/P1955

离散化+并查集

离线,先把(xi = xj)用并查集解决,再一个一个判断不等的是否矛盾

一开始用map离散化结果TLE

emm

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<map>
 7 #include<vector>
 8  
 9 using namespace std;
10 
11 const int MAXN = 100666;
12 int n, kx;
13 int fa[MAXN * 2], size[MAXN * 2], s[MAXN * 2];
14 vector< pair<int, int> > tf, li;
15 
16 
17 template <typename tn> void read (tn & a) {
18     tn x = 0, f = 1;
19     char c = getchar();
20     while (c < '0' || c > '9'){ if (c == '-') f = -1; c = getchar(); }
21     while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar(); }
22     a = f == 1 ? x : -x;
23 }
24 
25 int find (int x) {
26     if (fa[x] == x) return x;
27     return fa[x] = find(fa[x]);
28 } 
29 
30 void link (int x, int y) {
31     x = find(x);
32     y = find(y);
33     if (x == y) return;
34     if (size[x] > size[y]) { link(y, x); return; }
35     fa[x] = y;
36     size[y] += size[x];
37 }
38 
39 int ge (int x) {
40     int left = 1, right = kx + 1;
41     while (left < right - 2) {
42         int mid = (left + right) / 2;
43         if (s[mid] > x) right = mid; else left = mid;
44     }
45     if (s[left] == x) return left; else return left + 1;
46 }
47 
48 int main() {
49     int T;
50     read(T);
51     while (T--) {
52         read(n);
53         tf.clear(); li.clear();
54         for (int i = 1; i <= n; ++i) {
55             int x, y, k;
56             read(x);
57             read(y);
58             read(k);
59             if (k == 0) tf.push_back(make_pair(x, y)); else li.push_back((make_pair(x, y)));
60             s[i + i - 1] = x;
61             s[i + i] = y;
62         }
63         sort(s + 1, s + n + n);
64         int i = 1;
65         kx = 1;
66         while (i <= n * 2) {
67             int j = i;
68             while (j + 1 <= n * 2 && s[j + 1] == s[i]) ++j;
69             s[kx] = s[i];
70             i = j + 1;
71             ++kx;
72         }
73         --kx;
74         for (int i = 1; i <= n + n; ++i) fa[i] = i, size[i] = 1;
75         for (int i = 0; i < li.size(); ++i) {
76             int x, y;
77             x = li[i].first;
78             y = li[i].second;
79             x = ge(x);
80             y = ge(y);
81             link(x, y);
82         }
83         bool f = 1;
84         for (int i = 0; i < tf.size(); ++i) {
85             int x, y;
86             x = tf[i].first;
87             y = tf[i].second;
88             x = ge(x);
89             y = ge(y);
90             x = find(x);
91             y = find(y);
92             if (x == y) { f = 0; break; }
93         }
94         if (f) cout << "YES\n"; else cout << "NO\n";
95     }
96     return 0;
97 } 
View Code

 

posted on 2018-03-15 23:44  ^m  阅读(137)  评论(0编辑  收藏  举报