POJ 2492[带权并查集]

来源:互联网 发布:mysql数据库视频下载 编辑:程序博客网 时间:2024/05/17 09:29
A Bug's Life
Time Limit: 10000MS Memory Limit: 65536KTotal Submissions: 25074 Accepted: 8159

Description

Background 
Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their interactions were easy to identify, because numbers were printed on their backs. 
Problem 
Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.

Input

The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space. In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one.

Output

The output for every scenario is a line containing "Scenario #i:", where i is the number of the scenario starting at 1, followed by one line saying either "No suspicious bugs found!" if the experiment is consistent with his assumption about the bugs' sexual behavior, or "Suspicious bugs found!" if Professor Hopper's assumption is definitely wrong.

Sample Input

23 31 22 31 34 21 23 4

Sample Output

Scenario #1:Suspicious bugs found!Scenario #2:No suspicious bugs found!

Hint

Huge input,scanf is recommended.

   题意:

   有T个case,每个case开头包含N(1到2000)只虫子和M(1到1000000)个条件关系。每个条件关系都给出a和b,代表a和b可以进行交配,所以属于不同性别,当给出某条关系a和b是同性别的话,说明两只虫子是同性恋。在给出所有关系后,如果有同性恋,则输出Suspicious bugs found!如果没有的话,则输出No suspicious bugs found!

  

   思路:

   种类并查集,可以用带权的并查集来做。0代表是同性,1代表的是异性。



转载自:http://simone-chou.iteye.com/blog/1930207


#include<stdio.h>  #define max 2000+5  int root[max],rel[max];    int find(int a)  {      if(root[a]==a) return a;      int r=find(root[a]);      rel[a]=(rel[a]+rel[root[a]])%2;      root[a]=r;      return r;  }  //找根节点且路径压缩  int main()  {      int n;      scanf("%d",&n);      for(int j=1;j<=n;j++)      {          int m,t,temp=0;          scanf("%d%d",&m,&t);          for(int i=1;i<=m;i++)             root[i]=i,rel[i]=0;  //初始化,一开始自结成树,都为同性          while(t--)          {              int a,b;              int fa,fb;              scanf("%d%d",&a,&b);              fa=find(a);              fb=find(b);              if(fa!=fb)              {                  root[fa]=fb;                  rel[fa]=(rel[b]+1-rel[a]+2)%2;//只要rel[b]与rel[a]不同,那么更新a的上级fa为0,否则为1              }              else               {                  if((rel[a]-rel[b]+2)%2==0) temp=1;  //包含了1,1 即两个均为异性,和0,0(都是处点)            }  //因为要全部输完才判断是不是同性恋  //所以用temp来标记          }          printf("Scenario #%d:\n",j);          temp?printf("Suspicious bugs found!\n\n"):printf("No suspicious bugs found!\n\n");      }      return 0;  }  
以下为一种思路,转载自:http://www.cnblogs.com/ACShiryu/archive/2011/09/15/poj2492.html

题目有点怪,就是告诉你有n只虫子,m条信息,每一条信息的i和j有JQ,求出根据所给的信息能否判断出有搞基的虫子,并按照题目要求信息输出
这题用并查集解决起来很方便,当然搜索也可以解
首先分析第一组数据,则可知1和2异性,2和3也异性,可是1和3竟然也有JQ ,这是怎么回事?只能说他们在搞基,则输出Suspicious bugs found!
然后就是这题的处理办法,首先应该想到的是并查集,对于每一对有JQ的虫子,可以将他们分入到两个不同的并查集中,并记录跟这只虫子有JQ的虫子如果加入后存在冲突,则说明有搞基的虫子,没办法,这样就可以不用再考虑以后的虫子JQ了。
上面是大体思路,但有些小细节要考虑
如果那两只虫子之前都没有对象,都是处虫,则更新他们的对象信息;
如果只有其中的一个有对象,假设是a,而b没对象,则将b的对象更新为a,并且让a的对象和b同性,也就是入同一个并查集;
如果a和b都有对象,则有两种情况:
     a和b在同一个并查集里,则说明a和b有JQ,则可以不必考虑后面的虫子了;
     否则,将a和b之前的对象入同一个并查集,b和a之前的对象入同一个并查集;

0 0
原创粉丝点击