http://poj.org/problem?id=1703
*#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define N 100005
int n, m;
int p[N];
int ranks[N];
void init() {
for (int i = 1; i <= n; i++)
{
p[i] = i;
ranks[i] = 0;
}
}
int find(int x) {
if (x != p[x]) {
int temp = p[x];
p[x] = find(p[x]);
ranks[x] = (ranks[x] + ranks[temp]) % 2;
}
return p[x];
}
void build(int x, int y) {
int xx = find(x);
int yy = find(y);
if (xx != yy)
{
ranks[yy] = (ranks[x] - ranks[y] + 3) % 2;
p[yy] = xx;
}
}
int t;
int main() {
cin >> t;
char temp;
int x, y;
for (int k = 0; k < t; k++)
{
scanf("%d%d", &n, &m);
init();
cin.get();
for (int i = 0; i < m; i++) {
scanf("%c%d%d", &temp, &x, &y);
if (temp == 'A') {
int xx = find(x);
int yy = find(y);
if (xx == yy) {
if (ranks[x] == ranks[y]) {
cout << "In the same gang." << endl;
}
else
{
cout << "In different gangs." << endl;
}
}
else
cout << "Not sure yet." << endl;
}
else
{
build(x, y);
}
cin.get();
}
}
return 0;
}
http://poj.org/problem?id=2492
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define N 2005
using namespace std;
int n, m;
int p[N];
int ranks[N];
void init() {
for (int i = 1; i <= n; i++)
{
p[i] = i;
ranks[i] = 0;
}
}
int find(int x) {
if (x != p[x]) {
int temp = p[x];
p[x] = find(p[x]);
ranks[x] = (ranks[x] + ranks[temp]) % 2;
}
return p[x];
}
int main()
{
int t;
int ans = 1;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
init();
int x, y;
int flag = 1;
for (int i = 0; i < m; i++)
{
scanf("%d%d", &x, &y);
int xx = find(x);
int yy = find(y);
if (flag == 0)continue;
if (xx == yy)
{
if (ranks[x] == ranks[y]) {
flag = 0;
}
}
else
{
p[yy] = xx;
ranks[yy] = (ranks[x] - ranks[y] + 1) % 2;
}
}
if (flag == 1)
{
cout << "Scenario #" << ans++ << ":" << endl;
cout << "No suspicious bugs found!" << endl << endl;
}
else
{
cout << "Scenario #" << ans++ << ":" << endl;
cout << "Suspicious bugs found!" << endl << endl;
}
}
return 0;
}
http://poj.org/problem?id=1988
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
using namespace std;
#define N 30005
int uset[N];
int dist[N];
int n;
int find(int x) {
if (uset[x] < 0)
return x;
int temp = uset[x];
uset[x] = find(temp);
dist[x] = (dist[x] + dist[temp]);
return uset[x];
}
int main()
{
memset(uset, -1, sizeof(uset));
memset(dist, 0, sizeof(dist));
char trag;
int x, y;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> trag;
if (trag == 'M') {
cin >> x >> y;
int a = find(x);
int b = find(y);
if (a != b)
{
dist[b] = -uset[a];
uset[a] += uset[b];
uset[b] = a;
}
}
else
{
cin >> x;
y = find(x);
cout << (-uset[y]) - 1 - dist[x] << endl;
}
}
return 0;
}
http://poj.org/problem?id=1417
并查集加dp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<map>
#include<functional>
#define N 1005
using namespace std;
int n, p1, p2;
int p[N];
int ranks[N];
int bs[N];
int dp[N][N];
int bg[N][N];
int fs[N];
int ans = 1;
struct cmp {
bool operator()(int x,int y) {
return x > y;
}
};
set<int> q;
map<int, int>Q;
int find(int x)
{
if (x != p[x]) {
int temp = p[x];
p[x] = find(p[x]);
ranks[x] = (ranks[x] + ranks[temp]) % 2;
}
return p[x];
}
void build(int x1, int x2, string trag)
{
int xx = find(x1);
int yy = find(x2);
if (xx != yy) {
p[yy] = xx;
if (trag == "no")
ranks[yy] = (ranks[x2] - ranks[x1] + 3) % 2;
else
ranks[yy] = (ranks[x2] - ranks[x1] + 2) % 2;
}
}
void init()
{
q.clear();
Q.clear();
memset(dp, 0, sizeof(dp));
memset(bg, 0, sizeof(bg));
ans = 1;
for (int i = 1; i <= p1 + p2; i++) {
p[i] = i;
ranks[i] = 0;
}
}
void inster(int x,int v) {
if (q.count(x)) {
bg[fs[x]][v]++;
}
else
{
bs[ans] = x;
fs[x] = ans++;
bg[fs[x]][v]++;
q.insert(x);
}
}
int main()
{
priority_queue<int, vector<int>, cmp > ps;
string trag;
int x1, x2;
while (1)
{
scanf("%d%d%d", &n, &p1, &p2);
if (n == p1 && p1 == p2 && n == 0)
break;
init();
for (int i = 0; i < n; i++)
{
scanf("%d%d", &x1, &x2);
cin.get();
cin >> trag;
build(x1, x2, trag);
}
for (int i = 1; i <= p1 + p2; i++)
{
int f = find(i);
inster(f, ranks[i]);
}
dp[0][0] = 1;
for (int i = 1; i < ans; i++) {
for (int j = 0; j <= p1; j++) {
if (j >= bg[i][0])
dp[i][j] = dp[i - 1][j - bg[i][0]];
if(j>=bg[i][1])
dp[i][j] += dp[i - 1][j - bg[i][1]];
}
}
if (dp[ans - 1][p1] == 1) {
int re = p1;
for (int i = ans-1; i >= 1; i--) {
if (dp[i-1][re - bg[i][0]] == dp[i][re])
{
re = re - bg[i][0];
Q[bs[i]] = 0;
}
else
if (dp[i-1][re - bg[i][1]] == dp[i][re])
{
re = re - bg[i][1];
Q[bs[i]] = 1;
}
}
for (int i = 1; i <= p1 + p2; i++) {
int re = find(i);
if (ranks[i] == Q[re])
{
ps.push(i);
}
}
while (!ps.empty()) {
cout << ps.top() << endl;
ps.pop();
}
cout << "end" << endl;
}
else
cout << "no" << endl;
}
return 0;
}