这道题目我真心想死,,,
我真切的懂得了,写代码,你是一定要小心,并且全神贯注的去的,要不一点很小的错误都可以让你LTE,WA的想死,,所以写的时候千万要小心,另外,遇到自己解决不了的错误的时候,就算是对照别人写的代码看自己的代码都看不清楚的时候,就重新在敲一遍,说不定,豁然开朗的时候,也能改掉自己的错误...
以后千万要注意.
双重DFS求强连通量的算法实现起来是很方便的.首先是先用个正向的DNF将所有的点都访问以下,然后,将访问的点都存在一个数组内,并且将后访问的先存下.
然后再用逆DNS.当然用逆DNS之前你必须存着一个逆向边的图,然后再按照你存着的数组从后向前访问,就可以输出强连通数了,,如果是1的话那么就说明是强连通图,如果大于1了,当然肯定就是连通度为n的连通图咯,,
贴出代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define MAXN 100005
struct 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");
else
printf("No\n");
}
return 0;
}