一开始看教材的时候,不明白low是什么意思,不过现在稍微能够理解的就是,low可以看成是该点能够回到祖先被访问的时间点,而dfn则是深度,换句话说,就是访问的时间,所以只要把他理解为时间就好。
对于一个点而言,如果他的子孙的祖先的访问时间要小于他本身,那么也就是说他的子孙回到了他本身之上,那么这个时候该点就不能成为割点了,如果子孙的祖先的访问时间均大于他本身,那么也就是说他的子孙除了他之外没有更高位的祖先,那么该点肯定为割点。。
如果好好理解了上面这段话的意思,那看代码的话,就很容易看懂了。。。
View Code
1 #include2 #include 3 #include<string.h> 4 #define max(a,b) a>b?a:b 5 #define min(a,b) a 6 using namespace std; 7 #define Size 1002 8 int head[Size],dfn[Size],low[Size],sign[Size],Time; 9 int s,e; 10 struct ndoe 11 { 12 int start,end; 13 int next; 14 }edge[Size]; 15 void dfs(int cur) 16 { 17 dfn[cur]=low[cur]=Time++; 18 for(int i=head[cur];i!=-1;i=edge[i].next) 19 { 20 if(!dfn[edge[i].end]) 21 { 22 dfs(edge[i].end); 23 if(dfn[cur]<=low[edge[i].end]) 24 sign[cur]++; 25 else 26 low[cur]=min(low[cur],low[edge[i].end]); 27 } 28 else 29 low[cur]=min(low[cur],dfn[edge[i].end]); 30 } 31 } 32 int main() 33 { 34 int Count,num,T=0; 35 while(scanf("%d",&s)&&s) 36 { 37 num=Count=0; 38 Time=1; 39 memset(head,-1,sizeof(head)); 40 memset(dfn,0,sizeof(dfn)); 41 memset(low,0,sizeof(low)); 42 memset(sign,0,sizeof(sign)); 43 scanf("%d",&e); 44 edge[Count].start=s; 45 edge[Count].end=e; 46 edge[Count].next=head[s]; 47 head[s]=Count++; 48 edge[Count].start=e; 49 edge[Count].end=s; 50 edge[Count].next=head[e]; 51 head[e]=Count++; 52 while(scanf("%d",&s)&&s) 53 { 54 scanf("%d",&e); 55 edge[Count].start=s; 56 edge[Count].end=e; 57 edge[Count].next=head[s]; 58 head[s]=Count++; 59 edge[Count].start=e; 60 edge[Count].end=s; 61 edge[Count].next=head[e]; 62 head[e]=Count++; 63 num=max(num,s); 64 num=max(num,e); 65 } 66 for(int i=0;i<=num;i++)sign[i]=1; 67 sign[1]=0; 68 dfs(1); 69 int flag=0; 70 printf("Network #%d\n",++T); 71 for(int i=1;i<=num;i++) 72 { 73 if(sign[i]>1) 74 { 75 printf(" SPF node %d leaves %d subnets\n",i,sign[i]); 76 flag=1; 77 } 78 } 79 if(!flag)printf(" No SPF nodes\n"); 80 printf("\n"); 81 } 82 return 0; 83 }