Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 34621 | Accepted: 10675 |
Description
Input
Output
Sample Input
1 5 5 A 1 2 D 1 2 A 1 2 D 2 4 A 1 4
Sample Output
Not sure yet. In different gangs. In the same gang.
同1182思路。给出两种代码
对于每只动物创建2个元素i-A,i-B,并用这2 乘 N 个元素建立并查集。 这个并查集维护如下信息: 1,i-x 表示i属于种类x 。 2,并查集里的每一组表示组内所有元素代表的情况都同时发生或不发生。 例如,如果i-A和i-B在同一个组里,就表示如果i属于种类A那么j一定属于种类B,如果j属于种类B那么i一定属于种类A。 因此,对于每一条信息,只需要按照下面进行操作就可以了。 第一种:x和y属于异类 合并x-A和y-B,x-B和y-A;(x代表x-A,x+n代表x-B) 第二种:查询,判断x-A和y-A,x-A和y-B;
#include <cstdio> #include <cstring> #define MAX 200000+10 using namespace std; int set[MAX]; int n, m; void init() { for(int i = 1; i <= 2*n; i++) set[i] = i; } int find(int p) { int t; int child = p; while(p != set[p]) p = set[p]; while(child != p) { t = set[child]; set[child] = p; child = t; } return p; } void merge(int x, int y) { int fx = find(x); int fy = find(y); if(fx != fy) set[fx] = fy; } bool same(int x, int y) { return find(x) == find(y); } void slove() { int x, y; char a[2]; while(m--) { scanf("%s%d%d", a, &x, &y); if(a[0] == 'D') { merge(x+n, y); merge(x, y+n); } else if(a[0] == 'A') { if(same(x, y)) printf("In the same gang.\n"); else if(same(x, y+n)) printf("In different gangs.\n"); else printf("Not sure yet.\n"); } } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); init(); slove(); } return 0; }
代码二:
#include <cstdio> #include <cstring> #define MAX 100000+10 using namespace std; int set[MAX]; int vis[MAX];//记录动物i 第一次出现时 与它不同种类的动物 int n, m; void init() { for(int i = 1; i <= n; i++) { set[i] = i; vis[i] = 0; } } int find(int p) { int t; int child = p; while(p != set[p]) p = set[p]; while(child != p) { t = set[child]; set[child] = p; child = t; } return p; } void merge(int x, int y) { int fx = find(x); int fy = find(y); if(fx != fy) set[fx] = fy; } bool same(int x, int y) { return find(x) == find(y); } void slove() { int x, y; char a[2]; while(m--) { scanf("%s%d%d", a, &x, &y); if(a[0] == 'A') { if(same(x, y)) printf("In the same gang.\n"); //else if(!vis[x] && !vis[y]) else if(same(x, vis[y]))//此处不能用 vis[x] vis[y]判断 WA到死,改一下就过了。 求指教 printf("In different gangs.\n"); else printf("Not sure yet.\n"); } else if(a[0] == 'D') { if(vis[x])//没有出现过 { merge(vis[x], y); //合并vis[x] 和 y } else vis[x] = y; if(vis[y]) { merge(vis[y], x); } else vis[y] = x; } } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); init(); slove(); } return 0; }