c编写Strongly Connected Components

这是一个关于如何用C语言实现TARJAN算法来寻找有向图中的强连通分量的程序。程序包括了函数定义、示例输入输出以及具体的算法实现,其中`tarjan`函数是核心部分,用于遍历图并计算低点和编号,以确定强连通分量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Strongly Connected Components   (17分)

Write a program to find the strongly connected components in a digraph.

Format of functions:

void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) );

where Graph is defined as the following:

typedef struct VNode *PtrToVNode;
struct VNode {
    Vertex Vert;
    PtrToVNode Next;
};
typedef struct GNode *Graph;
struct GNode {
    int NumOfVertices;
    int NumOfEdges;
    PtrToVNode *Array;
};

Here void (*visit)(Vertex V) is a function parameter that is passed intoStronglyConnectedComponents to handle (print with a certain format) each vertex that is visited. The function StronglyConnectedComponents is supposed to print a return after each component is found.

Sample program of judge:

#include <stdio.h>
#include <stdlib.h>

#define MaxVertices 10  /* maximum number of vertices */
typedef int Vertex;     /* vertices are numbered from 0 to MaxVertices-1 */
typedef struct VNode *PtrToVNode;
struct VNode {
    Vertex Vert;
    PtrToVNode Next;
};
typedef struct GNode *Graph;
struct GNode {
    int NumOfVertices;
    int NumOfEdges;
    PtrToVNode *Array;
};

Graph ReadG(); /* details omitted */

void PrintV( Vertex V )
{
   printf("%d ", V);
}

void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) );

int main()
{
    Graph G = ReadG();
    StronglyConnectedComponents( G, PrintV );
    return 0;
}

/* Your function will be put here */

Sample Input (for the graph shown in the figure):

4 5
0 1
1 2
2 0
3 1
3 2

Sample Output:

3 
1 2 0

Note: The output order does not matter. That is, a solution like

0 1 2 
3

is also considered correct.



利用TARJAN算法


int Instack[MaxVertices];
int stack[MaxVertices];
int Num[MaxVertices];
int Low[MaxVertices];
int print[MaxVertices];
int counter=0;
int j=-1;
int m=0;
void tarjan(Graph G,void(*visit)(Vertex V),int v);
void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) )
{
int i=0;
for(i=0;i<G->NumOfVertices;i++){
if(Num[i]<=0)
tarjan(G,visit,i);
}
}
void tarjan(Graph G,void(*visit)(Vertex V),int v)
{
PtrToVNode W;
int w,p;
Low[v]=Num[v]=++counter;
Instack[v]=1;
stack[++j]=v;
for(W=G->Array[v];W!=NULL;W=W->Next){
w=W->Vert;

if(Num[w]<=0){
tarjan(G,visit,w);
Low[v]=Low[v]<Low[w]?Low[v]:Low[w];

}
else if(Instack[w]==1&&Num[w]<Low[v]){
Low[v]=Num[w];
 
}

}


if(Num[v]==Low[v]){
do{
p=stack[j--];
print[m++]=p;
Instack[p]=0;
}while(p!=v);
for(m=m-1;m>=0;m--){
(*visit)(print[m]);
}
printf("\n");
m=0;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值