HDU-1269(双DFS求强连通性)

来源:互联网 发布:seo文章编辑 编辑:程序博客网 时间:2024/05/20 23:57

这道题目我真心想死,,,

我真切的懂得了,写代码,你是一定要小心,并且全神贯注的去的,要不一点很小的错误都可以让你LTE,WA的想死,,所以写的时候千万要小心,另外,遇到自己解决不了的错误的时候,就算是对照别人写的代码看自己的代码都看不清楚的时候,就重新在敲一遍,说不定,豁然开朗的时候,也能改掉自己的错误...

以后千万要注意.

双重DFS求强连通量的算法实现起来是很方便的.首先是先用个正向的DNF将所有的点都访问以下,然后,将访问的点都存在一个数组内,并且将后访问的先存下.

然后再用逆DNS.当然用逆DNS之前你必须存着一个逆向边的图,然后再按照你存着的数组从后向前访问,就可以输出强连通数了,,如果是1的话那么就说明是强连通图,如果大于1了,当然肯定就是连通度为n的连通图咯,,

贴出代码:

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#define MAXN 100005struct Edge{int v;int next;}e1[MAXN],e2[MAXN];int N,M;//N represents the  number of points,and M stands for the number of edges;int visit1[10005],visit2[10005];int idx1,idx2;int head1[10005],head2[10005];int num[10005];int cn,nn;int belong[10005];void addedge_(int a,int b){idx1++;e1[idx1].v=b;e1[idx1].next=head1[a];head1[a]=idx1;idx2++;e2[idx2].v=a;e2[idx2].next=head2[b];head2[b]=idx2;}void DFS_1(int x){visit1[x]=1;for(int p=head1[x];p!=-1;p=e1[p].next){if(!visit1[e1[p].v])DFS_1(e1[p].v);}//printf("cn=%d x=%d ",cn,x);num[cn++]=x;}void DFS_2(int x){belong[x]=nn;visit2[x]=1;//printf("%d ",x);for(int p=head2[x];p!=-1;p=e2[p].next){if(!visit2[e2[p].v])DFS_2(e2[p].v);}}int main(){int a,b;while(scanf("%d%d",&N,&M),N|M){idx1=0;idx2=0;nn=0;cn=0;memset(visit1,0,sizeof(visit1));memset(visit2,0,sizeof(visit2));memset(head1,-1,sizeof(head1));memset(head2,-1,sizeof(head2));for(int i=1;i<=M;i++){scanf("%d%d",&a,&b);addedge_(a,b);}for(i=1;i<=N;i++){if(!visit1[i])DFS_1(i);}//printf("\n");//printf("%d\n",cn);for(int j=cn-1;j>=0;j--){if(!visit2[num[j]]){DFS_2(num[j]);nn++;}}//printf("\n");if(nn==1)printf("Yes\n");elseprintf("No\n");}return 0;}