POJ 2492 dfs
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; }