Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10618 Accepted Submission(s): 3451
2 3 3 1 2 2 3 1 3 4 2 1 2 3 4
Scenario #1: Suspicious bugs found! Scenario #2: No suspicious bugs found!HintHuge input,scanf is recommended.
#include <cstdio> #include <cstring> #define MAX 2000+10 using namespace std; int set[MAX]; int love[MAX];//存储第一个和i恋爱的人 int n, m; int k = 1; int exist; void init() { int i; for(i = 1; i <= n; i++) { set[i] = i; love[i] = 0;//初始化为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; } void search() { int i, x, y; exist = 0; for(i = 0; i < m; i++) { scanf("%d%d", &x, &y); if(exist)//已经找到 同性恋 下面不用处理 continue; if(find(x) == find(y))//他们在同一个集合 { exist = 1;//同性恋 continue; } if(love[x])//x已经有恋人 { merge(love[x], y);//与x恋爱的人 和 y必须是同一性别 合并同性 } else love[x] = y; if(love[y])//y已经有恋人 { merge(love[y], x);//与y恋爱的人 和 x必须是同一性别 合并同性 } else love[y] = x; } } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); init(); search(); printf("Scenario #%d:\n", k++); if(!exist) printf("No suspicious bugs found!\n"); else printf("Suspicious bugs found!\n"); printf("\n"); } return 0; }
对于每只动物创建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;
代码实现:
<pre class="cpp" name="code">#include <cstdio> #include <cstring> #include <algorithm> #define MAX 4000+10 using namespace std; int set[MAX]; int n, m; int k = 1; 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 input() { int x, y; int exist = 0; while(m--) { scanf("%d%d", &x, &y); if(exist) continue; if(same(x, y)) { exist = 1; continue; } merge(x, y+n); merge(x+n, y); } printf("Scenario #%d:\n", k++); if(exist) printf("Suspicious bugs found!\n\n"); else printf("No suspicious bugs found!\n\n"); } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &m); init(); input(); } return 0; }