POJ 2492 dfs

本文详细介绍了如何使用DFS解决POJ 2492昆虫组合问题,通过判断是否存在性别相异的昆虫组合,验证专家假设的正确性。文章提供了完整的C++代码实现。

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;
}

  

转载于:https://www.cnblogs.com/sdau10kuaile/archive/2012/01/18/2325999.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值