本文出自:http://blog.csdn.net/svitter
最近感觉做了不少的并查集的题目。发现A说B说的对,谁说假话谁说真话这种游戏,基本全是并查集。做下记录,防止以后忘记。
题目给出n句话,编号从1开始。每一句话都是类似:Sentence $num is true/false 这种形式。
最后输出真话最多的情况的真话个数。
注意scanf的格式,不能使用"Sentence %d is %s"这种格式。具体原因未知。可以使用%s不停的读入到不用的变量中来消除缓存区中的字符。
首先利用i, i+n这种取反的方法来判断对错。如果出现悖论,继续吸收缓冲区,但是不在进行计算。
具体方法可以参见:POJ2492 A Bug‘s Life (并查集)
求出相应集合以后,统计num[getRoot(i)]的个数,最后相加即可。
问题:
一开始连着getRoot(i+n)我也统计了,后来参照了大神的代码,考虑到i+n的情况属于i的对立情况,没有必要计算.
与i对立的情况必定是包含在除了i的情况中,所以没有必要进行统计。
在遍历num数组的过程中, 取num[getRoot(i)]和num[getRoot(i+n)]中较大的一组。即:取i或者~i。因为不存在悖论,所以i和~i必定有一个成立。
//author: svtter // #include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #define INF 0xffffff using namespace std; int root[2010]; int n; int num[2010]; int vis[2010]; void init() { for(int i = 0; i <= n*2; i++) root[i] = i; } int getRoot(int i) { if(i == root[i]) return i; return root[i] = getRoot(root[i]); } int a, b; void Merge(int i, int j) { a = getRoot(i); b = getRoot(j); if(a == b) return; root[a] = b; } bool jud(int i, int j) { return getRoot(i) == getRoot(j); } void solve() { int i, ans; ans = 0; memset(num, 0, sizeof(num)); memset(vis, 0, sizeof(vis)); for(i = 1; i <= n; i++) { num[getRoot(i)] ++; // num[getRoot(i+n)]++; } for(i = 1; i <= n; i++) { if(vis[getRoot(i)] || vis[getRoot(i+n)]) continue; ans += max(num[getRoot(i)], num[getRoot(i+n)]); vis[getRoot(i)] = vis[getRoot(i+n)] = 1; } printf("%d\n", ans); } int main() { char ju[10]; int i, t; bool paradox; while(~scanf("%d", &n)) { if(n == 0) break; paradox = false; //input init(); for(i = 1; i <= n; ++i) { scanf("%s", ju); scanf("%d", &t); scanf("%s", ju); scanf("%s", ju); if(paradox) continue; if(ju[0] == 'f') { if(jud(i, t) || jud(i+n, t+n)) paradox = 1; else { Merge(i, t+n); Merge(t, i+n); } } else { if(jud(i, t+n) || jud(t, i+n)) paradox = 1; else { Merge(i, t); Merge(i+n, t+n); } } } if(paradox) printf("Inconsistent\n"); else solve(); } return 0; }
POJ1291 This Sentence is False (并查集 || 哈希),布布扣,bubuko.com
POJ1291 This Sentence is False (并查集 || 哈希)
原文地址:http://blog.csdn.net/svitter/article/details/38312643