A Bug's Life

Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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

2
3 3
1 2
2 3
1 3
4 2
1 2
3 4
 

Sample Output

Scenario #1:
Suspicious bugs found!

Scenario #2:
No suspicious bugs found!

Hint

Huge input,scanf is recommended.
         
 题意: 有一堆虫,正常来说只能和异性有关系,现在给你一堆关系,问你这些中可能存在“同性恋”吗
思路1: (种类并查集) 除了正常的并查集之外,此题还要维护一个关系数组记录它与其父亲的性别关系,这个关系一般自己定义,
此题可以认为是同性为 1 , 异性为0 ,那么要找到它与其父亲的父亲的关系就可以使(rank[x]+rank[x+1] )%2 ,依次递归下去就可以得到它和他最上面的祖先的关系
并查集一般就考虑并,和查两部分,其中压缩路径的时候要注意将关系数组也要更新,
 #include <cstdio>
//存储的是其父亲的下表
int bugs[];
int relation[];//1:相同性别 0:不同性别
//初始化
void init(int len)
{
for(int i = ;i <= len; i++)
{
bugs[i] = i;
relation[i] = ;
}
}
//找到根
int find(int bug)
{
if(bugs[bug]==bug)return bug;
int tem = bugs[bug];
bugs[bug] = find(bugs[bug]);//递归更新域,返回最终的父亲节点,把所有的孩子都更新了
//注意这里,求当前位置和父亲的关系,记录之前父亲的位置为tem,然后因为是递归,
//此时的relation[tem]已经在递归中更新过了,也就是孩子和父亲的关系+父亲和爷爷的关系+1然后模2就得到
//孩子和爷爷的关系,这里用0和1表示,0表示不同性别,1表示相同性别
relation[bug] = (relation[bug]+relation[tem]+)%;
return bugs[bug];
} void union_set(int a,int b,int x,int y)
{
//合并,让前边的集合的根指向后边集合的根,成为一个集合
bugs[x]=y;
//更新前边集合根和新的集合根之间的关系,
//注意这里,relation[a]+relation[x]与relation[b]
//相对于新的父节点必须相差1个等级,因为他们不是gay
relation[x] = (relation[b]-relation[a])%; //这里的种类函数还是不理解,大概是根据一个关系的环状推出关系
} int main()
{
int S;
int n,inter;
int bug1,bug2,parent1,parent2;
bool flag;//false:无同性恋,true:有同性恋
scanf("%d",&S);
for(int i=; i<=S;i++)
{
scanf("%d%d",&n,&inter);
flag = false;
init(n);//初始化,使其父节点为自己
for(int j = ; j <= inter; j++)
{
scanf("%d%d",&bug1,&bug2);
if(flag)continue;// 因为当有同性的时候是依次读入的数据,要保证数据时读完的所以用continue
parent1 = find(bug1);
parent2 = find(bug2);
if(parent1==parent2)
{
if(relation[bug1]==relation[bug2])//同性
flag = true;
}
union_set(bug1,bug2,parent1,parent2);
}
if(flag)
printf("Scenario #%d:\nSuspicious bugs found!\n",i);
else
printf("Scenario #%d:\nNo suspicious bugs found!\n",i);
printf("\n");
}
return ;
}

下面是dfs的思路,将所有的关系都用链接表的形式存起来,然以后肯定会有环的情况,当时奇环的时候(定点数是基数的时候)就存在同性恋,要是偶环就是不存在同性恋,扫描的时候统计节点数,当再次扫描到同一个点的时候看扫描过得点数是奇还是偶。

 #include <cstdio>
#include <cstring>
using namespace std;
#define N 2005
#define M 1000005 int head[N];
struct Edge{
int v, next;
}edge[*M];
int Ecnt; void init()
{
Ecnt = ;
memset(head, -, sizeof(head));
} void add(int u, int v)
{
edge[Ecnt].v = v;
edge[Ecnt].next = head[u];
head[u] = Ecnt++;
edge[Ecnt].v = u;
edge[Ecnt].next = head[v];
head[v] = Ecnt++;
}//存双向边 bool visited[N];
int f[N];//统计它是男生还是女生,定义 男生是1 女生是0 搜索的时候按0,1,0,1 的顺序标记点,如果再次访问到原先的点的时候应该按顺序标的值与其之前标的不一样的话就是奇环
bool dfs(int u)
{
for(int i = head[u]; i != -; i = edge[i].next)//遍历每一条边
{
int v = edge[i].v;//下一个点
if(!visited[v])//如果没有访问过这个点
{
visited[v] = ;
f[v] = (-f[u]); //按0,1 交替顺序的标记点
bool res = dfs(v);//如果在这之前就已经发现有奇环的话就直接返回FALSE
if(res == false) return false;
}
else if(f[u] == f[v]) return false;//最后又访问到了这个点,就判断这两个点是否是同一个值
}
return true;
} int main()
{
int T, n, m;
scanf("%d", &T);
int cas = ;
while(T--)
{
printf("Scenario #%d:\n", cas++);
scanf("%d %d", &n, &m);
init();
int s, t;
for(int i = ; i < m; i++)
{
scanf("%d %d", &s, &t);
add(s, t);
}
memset(visited, , sizeof(visited));
memset(f, -, sizeof(f));
bool ans = true;
for(int i = ; i <= n; i++)
{
if(!visited[i])
{
visited[i] = ;
f[i] = ;
bool res = dfs(i);
if(res == false)
{
ans = false;
break;
}
}
}
if(ans) puts("No suspicious bugs found!\n");
else puts("Suspicious bugs found!\n");
}
return ;
}
 

A Bug's Life(种类并查集)(也是可以用dfs做)的更多相关文章

  1. 【POJ】2492 A bug's life ——种类并查集

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28211   Accepted: 9177 De ...

  2. POJ2492 A Bug's Life —— 种类并查集

    题目链接:http://poj.org/problem?id=2492 A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Su ...

  3. hdoj 1829 A bug's life 种类并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1829 并查集的一个应用,就是检测是否存在矛盾,就是两个不该相交的集合有了交集.本题就是这样,一种虫子有 ...

  4. HDU 1829 A Bug's Life(种类并查集)

    思路:见代码吧. #include <stdio.h> #include <string.h> #include <set> #include <vector ...

  5. hdu1829A Bug's Life(种类并查集)

    传送门 关键在于到根节点的距离,如果两个点到根节点的距离相等,那么他们性别肯定就一样(因为前面如果没有特殊情况,两个点就是一男一女的).一旦遇到性别一样的,就说明找到了可疑的 #include< ...

  6. 【进阶——种类并查集】hdu 1829 A Bug's Life (基础种类并查集)TUD Programming Contest 2005, Darmstadt, Germany

    先说说种类并查集吧. 种类并查集是并查集的一种.但是,种类并查集中的数据是分若干类的.具体属于哪一类,有多少类,都要视具体情况而定.当然属于哪一类,要再开一个数组来储存.所以,种类并查集一般有两个数组 ...

  7. HDU 1829 A Bug's Life (种类并查集)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1829 A Bug's Life Time Limit: 15000/5000 MS (Java/Oth ...

  8. POJ2492:A Bug's Life(种类并查集)

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 45757   Accepted: 14757 题 ...

  9. poj 2492 A Bug's Life 二分图染色 || 种类并查集

    题目链接 题意 有一种\(bug\),所有的交往只在异性间发生.现给出所有的交往列表,问是否有可疑的\(bug\)(进行同性交往). 思路 法一:种类并查集 参考:https://www.2cto.c ...

随机推荐

  1. GVIM与模板——让FPGA开发变得更简单

    还在使用FPGA开发环境自带的代码编辑器?还在逐个字母敲击冗长重复的代码?明德扬至简设计法让你快速提高代码编写效率!利用GVIM这一高效的编辑工具并添加自定义模板,通过简短的脚本命令即可自动生成所有常 ...

  2. ES6中Promise对象个人理解

    Promise是ES6原生提供的一个用来传递异步消息的对象.它减少了传统ajax金字塔回调,可以将异步操作以同步操作的流程表达出来使得代码维护和可读性方面好很多. Promise的状态: 既然是用来传 ...

  3. bzoj 2109: [Noi2010]Plane 航空管制

    Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的 ...

  4. js的Date对象

    1.构造Date对象 var dt = new Date(); //获取当地包含日期和时间的对象,格式为:Thu Aug 31 2017 09:15:43 GMT+0800 (中国标准时间) 2.使用 ...

  5. jquery通过ajax查询数据动态添加到select

    function addSelectData() { //select的id为selectId //清空select中的数据 $("#selectId").empty(); $.a ...

  6. Mysql中字符集总结

    有时候,在Mysql数据库中会经常遇到乱码的问题,现在普遍的做法就是全部强行把编码格式都设置成utf8模式,就可以解决这个问题,以前是知其然,不知其所以然,今天我就稍微研究了下Mysql的字符集. 就 ...

  7. Django__Ready

    Python WEB框架 : DJango : 大而全 flask : 小而精 tornado : 下载DJango : PIP3 INSTALL DJANGO 创建DJango项目 : django ...

  8. python科学计算_numpy_广播与下标

    多维数组下标 多维数组的下标是用元组来实现每一个维度的,如果元组的长度比维度大则会出错,如果小,则默认元组后面补 : 表示全部访问: 如果一个下标不是元组,则先转换为元组,在转换过程中,列表和数组的转 ...

  9. Java中对List<E>按E的属性排序的简单方法

    这是LeetCode上的题目56. Merge Intervals中需要用到的, 简单来说,定义了E为 /** * Definition for an interval. * public class ...

  10. Pycharm选择pyenv安装的Python版本

    在macOS上使用pyenv实现Python多版本共存后,pyenv安装的Python版本存在于macOS下的 ~/.pyenv/versions/下. 在Pycharm时,选择此目录下对应的版本即可 ...