链接http://acm.hdu.edu.cn/showproblem.php?pid=1269
求强连通分支的题,为了搞定2-sat问题,开始找这些题做,而且用的是gabow算法,是为了给自己打模板才做的这道题
View Code
#include<stdio.h> #include<string.h> #define M 100005 #define N 10005 int head[N]; int t,cnt0,cnt1; int stk1[N],stk2[N]; int top1,top2; int time[N],sc[N]; struct edge { int v; int next; }; edge e[M]; void init() { memset(head,-1,sizeof(head)); memset(time,-1,sizeof(time)); memset(sc,-1,sizeof(sc)); t=0; cnt0=0; cnt1=0; top1=0; top2=0; } void add(int u,int v) { e[t].v=v; e[t].next=head[u]; head[u]=t++; } void gabow(int u) { time[u]=cnt0++; stk1[top1++]=u; stk2[top2++]=u; int i,j,v; for(i=head[u];i>=0;i=e[i].next) { v=e[i].v; if(time[v]==-1) gabow(v); else if(sc[v]==-1) while(time[stk2[top2-1]]>time[v])//如果访问过但是没有归入任何的scc则可以说明这是一个环 top2--; } if(stk2[top2-1]!=u) return; top2--; do { sc[stk1[--top1]]=cnt1;//归入scc }while(stk1[top1]!=u); cnt1++; } int main() { int n,m,i,j,k,a,b; while(scanf("%d%d",&n,&m)&&(n||m)) { init(); for(i=0;i<m;i++) { scanf("%d%d",&a,&b); add(a,b); } gabow(1); for(i=1;i<=n;i++) if(sc[i]) break; if(i>n) printf("Yes\n"); else printf("No\n"); } return 0; }