poj1182和ural1003
2014-06-28 00:18
281 查看
poj1182
并查集的运用,集合之间的关系表示,增加一个字段来表示和跟的关系r[x]
如果r[x] == 0表示和根同类,r[x] == 1表示根吃x,r[x] == 2表示x吃根。
那么现在如果x,y的关系为r[y],y,z的关系为r[z],那么x和z的关系则是(r[y] + r[z]) % 3。不妨画个图看看。
现在读入一个陈述:
1.如果x,y在同一个集合里面:
1. 1 x y陈述x,y是同类,
那么根据他们与根的关系来判断,如果r[x] != r[y],则说明他们不是同类
2. 2 x y陈述x吃y,那么x与根的关系为r[x],y与根的关系为r[y],那么根与x的关系为3 - r[x],
所以y与x的关系为3 - r[x] + r[y],x吃y,则表示为 (3 - r[x] + r[y]) % 3 == 1。明显以x为根的话,y对x关系就是1.
如果x,y不在一个集合里面,则合并集合,
现在要修改根的关系。
首先father[x]和x的关系为r[x],x和y的关系为d - 1,那么father[x]和y的关系为 r[x] + d - 1;
father[y]和y的关系为r[y],那么y和father[y]的关系为3 - r[y],那么father[x]和father[y]的关系为 r[x] + d - 1 + 3 - r[y]。
更新r[father[y]]即可。
ural1003:
与poj1182类似。
i, j为偶,则说明i和j - 1的关系为同奇偶。
同理表示为不同奇偶。
r[x] == 0表示和根同奇偶,r[x] == 1表示和根不同奇偶。
那么关系更改就简单很多了比poj1182.
注意一点是,首先要离散化,离散化之后还要注意规定了一个长度,如果他说的大于这个长度很定是假的。
然后答案可能是0.
poj1182
AC代码
ural1003
并查集的运用,集合之间的关系表示,增加一个字段来表示和跟的关系r[x]
如果r[x] == 0表示和根同类,r[x] == 1表示根吃x,r[x] == 2表示x吃根。
那么现在如果x,y的关系为r[y],y,z的关系为r[z],那么x和z的关系则是(r[y] + r[z]) % 3。不妨画个图看看。
现在读入一个陈述:
1.如果x,y在同一个集合里面:
1. 1 x y陈述x,y是同类,
那么根据他们与根的关系来判断,如果r[x] != r[y],则说明他们不是同类
2. 2 x y陈述x吃y,那么x与根的关系为r[x],y与根的关系为r[y],那么根与x的关系为3 - r[x],
所以y与x的关系为3 - r[x] + r[y],x吃y,则表示为 (3 - r[x] + r[y]) % 3 == 1。明显以x为根的话,y对x关系就是1.
如果x,y不在一个集合里面,则合并集合,
现在要修改根的关系。
首先father[x]和x的关系为r[x],x和y的关系为d - 1,那么father[x]和y的关系为 r[x] + d - 1;
father[y]和y的关系为r[y],那么y和father[y]的关系为3 - r[y],那么father[x]和father[y]的关系为 r[x] + d - 1 + 3 - r[y]。
更新r[father[y]]即可。
ural1003:
与poj1182类似。
i, j为偶,则说明i和j - 1的关系为同奇偶。
同理表示为不同奇偶。
r[x] == 0表示和根同奇偶,r[x] == 1表示和根不同奇偶。
那么关系更改就简单很多了比poj1182.
注意一点是,首先要离散化,离散化之后还要注意规定了一个长度,如果他说的大于这个长度很定是假的。
然后答案可能是0.
poj1182
AC代码
#include <cstdio> #include <cstring> const int maxn = 50007; int father[maxn], r[maxn]; int find(int a) { if (a == father[a]) { return a; } else { int t = father[a]; father[a] = find(father[a]); r[a] = (r[a] + r[t]) % 3; return father[a]; } } void union_set(int a, int b, int d) { int x = find(a); int y = find(b); father[y] = x; r[y] = (r[a] + d - 1 + 3 - r[b]) % 3; } int main() { // freopen("input.txt", "r", stdin); int n, m; int ans = 0; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { father[i] = i; r[i] = 0; } while (m--) { int type, a, b; scanf("%d%d%d", &type, &a, &b); if (a > n || b > n || (type == 2 && a == b)) { ans++; continue; } int x = find(a); int y = find(b); if (x == y) { if ((type == 1 && (r[a] != r[b]))) { ans++; } else if (type == 2 && (3 - r[a] + r[b]) % 3 != 1) { ans++; } } else { union_set(a, b, type); } } printf("%d\n", ans); return 0; }
ural1003
#include <cstdio> #include <cstring> #include <map> #include <algorithm> using namespace std; const int maxn = 5007; struct Seg { int left, right, type; }; struct Seg seg[maxn]; int father[maxn], r[maxn], ar[maxn], length, cnt; map<int, int> maps; void init() { length = 1; for (int i = 2; i <= cnt; i++) { if (ar[i] != ar[i - 1]) { length++; ar[length] = ar[i]; } } } int find(int x) { if (x == father[x]) { return x; } else { int t = father[x]; father[x] = find(father[x]); r[x] = (r[x] + r[t]) % 2; return father[x]; } } int binarySearch(int a) { int low = 1; int high = length; while (low <= high) { int mid = (low + high) >> 1; if (ar[mid] == a) { return mid; } else if (ar[mid] > a) { high = mid - 1; } else { low = mid + 1; } } return -1; } void union_set(int a, int b, int type) { int x = find(a); int y = find(b); father[y] = x; r[y] = (r[a] + type + 2 - r[b]) % 2; } int main() { // freopen("input.txt", "r", stdin); while (scanf("%d", &length) != EOF) { if (length == -1) { break; } int m; scanf("%d", &m); maps.clear(); cnt = 0; int flag = 0; int s_m = m; for (int i = 1; i <= m; i++) { int a, b; char even[30]; scanf("%d%d%s", &a, &b, even); if (!flag && (a > length || b > length)) { flag = 1; s_m = i - 1; } ar[++cnt] = a - 1; ar[++cnt] = b; seg[i].left = a - 1; seg[i].right = b; if (even[0] == 'e') { seg[i].type = 0; } else { seg[i].type = 1; } } sort(ar + 1, ar + 1 + cnt); init(); int ans = 0; for (int i = 1; i <= length; i++) { father[i] = i; r[i] = 0; } for (int i = 1; i <= m && i <= s_m; i++) { int left = binarySearch(seg[i].left); int right = binarySearch(seg[i].right); int x = find(left); int y = find(right); if (x == y) { if (seg[i].type == 0 && r[left] != r[right]) { break; } else if (seg[i].type == 1 && (r[left] + r[right]) != 1) { break; } } else { union_set(left, right, seg[i].type); } ans = i; } printf("%d\n", ans); } }
相关文章推荐
- Ural 1003 Parity
- PKU1733 URAL1003 Parity game
- URAL1003 Parity
- URAL 1003 Parity
- URAL 1003 Parity(并查集)
- Ural(Timus) 1003 Parity
- Ural 1003 Parity(并查集)
- ural 1003 Parity 并查集
- Ural_1003 Parity(并查集)
- URAL 1003 并查集
- URAL 1003,1004
- ural 1003. Parity(并查集)
- ural1003
- URAL 1349. Farm (费马大定理)
- URAL 1196. History Exam (二分)
- URAL 1727. Znaika's Magic Numbers(数学 vector)
- URAL 1614. National Project “Trams” [ 构造 欧拉回路 ]
- poj1003
- URAL 1157. Young Tiler (数学啊 )
- URAL 1639. Chocolate 2