ACM内部函数9

五、图论

1.Prim算法求最小生成树

语法:

prim(Graph G,int vcount,int father[]);

参数:

G:图,用邻接矩阵表示

vcount:表示图的顶点个数

father[]:用来记录每个节点的父节点

返回值:

null

注意:

常数max_vertexes为图最大节点数

常数infinity为无穷大

源程序:

#define infinity 1000000

#define max_vertexes 5 

typedef int Graph[max_vertexes][max_vertexes];

void prim(Graph G,int vcount,int father[])

{

    int i,j,k;

    int lowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes];

    for (i=0;i<vcount;i++)

        {

        lowcost[i]=G[0][i];

        closeset[i]=0; 

        used[i]=0;

        father[i]=-1; 

        }

    used[0]=1; 

    for (i=1;i<vcount;i++)

        {

        j=0;

        while (used[j]) j++;

        for (k=0;k<vcount;k++)

            if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;

        father[j]=closeset[j]; 

        used[j]=1;

        for (k=0;k<vcount;k++)

            if (!used[k]&&(G[j][k]<lowcost[k]))

                { lowcost[k]=G[j][k];

                closeset[k]=j; }

        }

}

2.Dijkstra算法求单源最短路径

语法:

result=Dijkstra(Graph G,int n,int s,int t, int path[]);

参数:

G:图,用邻接矩阵表示

n:图的顶点个数

s:开始节点

t:目标节点

path[]:用于返回由开始节点到目标节点的路径

返回值:

最短路径长度

注意:

输入的图的权必须非负

顶点标号从0开始

用如下方法打印路径:

    i=t;

    while (i!=s)

        {

        printf("%d<--",i+1);

        i=path[i];

        }

    printf("%d/n",s+1); 

源程序:

int Dijkstra(Graph G,int n,int s,int t, int path[])

{

    int i,j,w,minc,d[max_vertexes],mark[max_vertexes];

    for (i=0;i<n;i++) mark[i]=0;

    for (i=0;i<n;i++)

        { d[i]=G[s][i];

        path[i]=s; }

    mark[s]=1;path[s]=0;d[s]=0;

    for (i=1;i<n;i++)

        {

       minc=infinity;

        w=0;

        for (j=0;j<n;j++)

            if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}

        mark[w]=1;

        for (j=0;j<n;j++)

        if ((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j]))

            { d[j]=d[w]+G[w][j];

            path[j]=w; }

        }

    return d[t];

}

3.Bellman-ford算法求单源最短路径

语法:

result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);

参数:

G:图,用邻接矩阵表示

n:图的顶点个数

s:开始节点

t:目标节点

path[]:用于返回由开始节点到目标节点的路径

success:函数是否执行成功

返回值:

最短路径长度

注意:

输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0

顶点标号从0开始

用如下方法打印路径:

    i=t;

    while (i!=s)

        {

        printf("%d<--",i+1);

        i=path[i];

        }

    printf("%d/n",s+1); 

源程序:

int Bellman_ford(Graph G,int n,int s,int t,int path[],int success)

{

    int i,j,k,d[max_vertexes];

    for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}

    d[s]=0;

    for (k=1;k<n;k++)

        for (i=0;i<n;i++)

            for (j=0;j<n;j++)

                if (d[j]>d[i]+G[i][j]) {d[j]=d[i]+G[i][j];path[j]=i;}

    success=0;

    for (i=0;i<n;i++)

        for (j=0;j<n;j++)

            if (d[j]>d[i]+G[i][j]) return 0;

    success=1;

    return d[t];

}

4.Floyd-Warshall算法求每对节点间最短路径

语法:

Floyd_Washall(Graph G,int n,Graph D,Graph P);

参数:

G:图,用邻接矩阵表示

n:图的顶点个数

DD[i,j]表示从ij的最短距离

PP[i,j]表示从ij的最短路径上的父节点 

返回值:

null

源程序:

void Floyd_Washall(Graph G,int n,Graph D,Graph P)

{

    int i,j,k;

    for (i=0;i<n;i++)

        for (j=0;j<n;j++)

            { D[i][j]=G[i][j];

                P[i][j]=i; }

    for (i=0;i<n;i++) { D[i][i]=0;P[i][i]=0; }

    for (k=0;k<n;k++)

        for (i=0;i<n;i++)

            for (j=0;j<n;j++)

                if (D[i][j]>D[i][k]+D[k][j])

                    { D[i][j]=D[i][k]+D[k][j];

                        P[i][j]=P[k][j]; }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值