http://poj.org/problem?id=1703
题意:第一行表示有多少测试用例。第二行n,m表示用多少个人以及下面有多少命令。其中如果是A则代表询问你A后面的这两人是不是一伙如果一伙则输出In the same gang..如果不是一伙则输出In different gangs.如果不确定输出Not sure yet。D代表的是D后面的两个人在不同的一伙。
*#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
题意: 有t组测试数据, 对于每组数据,第一行n, m分别表示昆虫的数目和接下来m行x, y,
x, y表示教授判断x, y为异性, 问教授是否有错误判断,即存在x, y为同性;
#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
给你一堆盒子,然后两种指令,M X Y,把含有x的一堆盒子放到含有y的盒子堆上面,C x,问x下面有多少个盒子
#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
给你p1个好人和p2个坏人,编号为1-p1+p2,然后给你n中操作
x1 x2 no:x1说x2不是好人
x1 x2 yes:x1说x2是好人
在这里好人说的总是对的,坏人说的总是坏的,然后问你最后能不能唯一确定哪些是好人,并输出,否则输出”no“
并查集加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;
}