poj 並查集高階應用——1703,2492,1988,1417
阿新 • • 發佈:2018-12-23
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;
}