http://poj.org/problem?id=2492
题意:一专家假设:一种昆虫,是不是性别不一样才会组合到一起 。给出n个昆虫,m个组合,验证是不是 性别相异的才会组合
开始的思路,想到并查集了,可是想到最后可能会分成两组以上,没什么思路
后来用的dfs 也写了好长时间
思路:点和边形成的图形如果没有回路肯定假设正确,即只有性别不同的才会组合到一起
如果有回路,回路中点的个数为奇数 则假设错误 如果为偶数则假设正确
这些是在纸上画了画得出的结论,下面的代码就是按这个思路写的
这么多代码就是围绕这一点思路
if(visit[t]&&(s_step-step[t])%2==0
&&s_step-step[t]>1)
{
bl=true;
return;
}
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int s_edge;
int visit[2005],head[2005],step[2005];
bool bl;
struct edge
{
int u;
int v;
int next;
};
edge e[2000005];//开始写的1000005 WA了一次 注意 双向边
void addedge(int a,int b)//加边!!!
{
s_edge++;
e[s_edge].u=a;
e[s_edge].v=b;
e[s_edge].next=head[a];
head[a]=s_edge;
s_edge++;
e[s_edge].u=b;
e[s_edge].v=a;
e[s_edge].next=head[b];
head[b]=s_edge;
}
void dfs(int x,int s_step)//点 点的步数
{
int y;
y=head[x];//点的第一条边
while(y)
{ int t=e[y].v;//下一个点
if(visit[t]&&(s_step-step[t])%2==0
&&s_step-step[t]>1)
{
bl=true;
return;
}
if(!visit[t])
{
visit[t]=1;
step[t]=s_step+1;
dfs(t,s_step+1);
if(bl)return;//注意 没有visit[t]=0这个回溯,还是要好好考虑下dfs的过程,本来写上visit[t]=0还想用并查集找总的几何数来,这样就不用了
}
y=e[y].next;
}
}
int main()
{
int CASE,cas;
int i,n,edg,a,b;
scanf("%d",&CASE);
for(cas=1;cas<=CASE;cas++)
{
scanf("%d%d",&n,&edg);
s_edge=0;
memset(head,0,sizeof(head));
for(i=1;i<=edg;i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
memset(visit,0,sizeof(visit));
bl=false;
for(i=1;i<=n;i++)
{
if(!visit[i])
{
visit[i]=1;
step[i]=1;
dfs(i,1);
if(bl)break;
}
}
printf("Scenario #%d:\n",cas);
if(bl)
printf("Suspicious bugs found!\n\n");
else
printf("No suspicious bugs found!\n\n");
}
return 0;
}