/* 深さ優先探索によってグラフの関節点を求めるアルゴリズムのプログラム例 */ #include #include #define N 100 /* 節点数の上限 */ #define M 500 /* 枝数の上限 */ struct edge /* 構造体edgeの定義 */ { int end1, end2; }; struct cell /* 構造体cellの定義 */ { int adj; int edge; struct cell *next; }; struct number /* 構造体numberの定義 */ { int v, e, lowpt; }; /* 関数の宣言 */ void artic(struct edge *E, int *art, int n, int m); struct number dfs(int v, struct number data, struct cell **adjlist, int *num, int *pre, int *lowpt, int *escan); main() /* グラフG =(V, E)の関節点を求めるテストプログラム */ { struct edge E[M]; /* グラフの枝集合 */ int art[N]; /* jが関節点ならart[j]==1, さもなければ0 */ int i, n, m; FILE *file; file=fopen("graphdata", "r"); { fscanf(file, "%d", &n); fscanf(file, "%d", &m); } for(i=0; iadj=v2; r->edge=i; r->next=adjlist[v1]; adjlist[v1]=r; q=(struct cell *)malloc(sizeof(struct cell)); q->adj=v1; q->edge=i; q->next=adjlist[v2]; adjlist[v2]=q; } u=0; /* 始点0から深さ優先探索 */ num[u]=0; lowpt[u]=num[u]; data.v=1; data.e=0; data=dfs(u, data, adjlist, num, pre, lowpt, escan); for(v=0; v0 && lowpt[v]>=num[u]) art[u]=1; /* uは関節点 */ } if(ucount>1) art[0]=1; /* 節点0の条件チェック */ printf("num, pre, lowpt, art\n"); for(j=0; jedge; if(escan[i]==-1) /* 枝iは未走査 */ { escan[i]=data.e; data.e=data.e+1; uadj=p->adj; if(num[uadj]==-1) /* 枝iの先の節点uadjは未探索 */ { num[uadj]=data.v; /* T(G)にuadjを追加 */ pre[uadj]=u; lowpt[uadj]=num[uadj]; data.v=data.v+1; /* uadjから深さ優先探索の再帰呼出し */ data=dfs(uadj, data, adjlist, num, pre, lowpt, escan); if(data.lowptnext; /* 隣接リストの次の枝 */ } data.lowpt=lowpt[u]; /* lowptの更新 */ return(data); }