Kruskal算法-图由邻接表实现

来源:互联网 发布:淘客怎么登陆淘宝客 编辑:程序博客网 时间:2024/06/13 02:08
#include<iostream>#define Vnum 10#define MAX 10000#include<string.h>#include<algorithm>using namespace std;typedef char Datatype;typedef struct arcnode{    int adjvex;    int weight;    struct arcnode *nextarc;} arcnode;typedef struct{    Datatype vexdata;    arcnode *firstarc;} Adjlist;typedef struct{    int arcnum,vexnum;    Adjlist adjlist[Vnum];} GraphTp;int visit[Vnum];int quan[Vnum][Vnum];void creat(GraphTp *g){    int i,j,k,ii,quanz;    char tailarc,headarc;    arcnode *p;    cout<<"enter vexnum and arcnum:"<<endl;    cin>>g->vexnum>>g->arcnum;    cout<<"enter the vexdata:"<<endl;    for(i=0; i<g->vexnum; i++)    {        cin>>g->adjlist[i].vexdata;        g->adjlist[i].firstarc=NULL;    }    cout<<"enter the arcdata:"<<endl;    for(ii=0; ii<g->arcnum; ii++)    {        cin>>tailarc>>headarc>>quanz;        for(k=0; k<g->vexnum; k++)            if(g->adjlist[k].vexdata==tailarc)            {                i=k;                break;            }        for(k=0; k<g->vexnum; k++)            if(g->adjlist[k].vexdata==headarc)            {                j=k;                break;            }        p=new arcnode;        p->adjvex=j;        p->weight=quanz;        quan[i][j]=quanz;        quan[j][i]=quanz;        cout<<"the data is:"<<i<<' '<<j<<' '<<quanz<<endl;        p->nextarc=g->adjlist[i].firstarc;        g->adjlist[i].firstarc=p;    }}struct edge{    int weight;    int u,v;} bian[Vnum];int cmp(edge A,edge B){    return A.weight<B.weight;}void Kruskal(int n,int C[Vnum][Vnum])     //Kuruskral算法,顶点数n,带权临接矩阵V[n][n]{    int i,j;    int nodeset[n];                       //顶点所属集合,之后用于判断顶点是否在同一暂时的树中    int count=0;    bool flag[n];                         //该数组用来判断顶点是否已经被选进生成树中    for(i=0; i<n; i++)                    //将图中所有边存入数组边中    {        nodeset[i]=i;        flag[i]=false;        for(j=0; j<n; j++)            if(C[i][j]<MAX)            {                bian[count].u=i;                bian[count].v=j;                bian[count].weight=C[i][j];                count++;            }    }    sort(bian,bian+count,cmp);           /*将图中各边权值升序排列*/    int edgeset=0;    int w=0;                             /*用来存放生成树总权值*/    count=0;    while(edgeset<n-1)                   /*核心算法*/    {        if(!flag[bian[count].u] && flag[bian[count].v])   /*u未加入某一集合,v已经加入某个集合, 这个集合由已经找到的生成树顶点组成,开始可能形成多个*/        {            w+=bian[count].weight;            flag[bian[count].u]=true;            nodeset[bian[count].u]=nodeset[bian[count].v];            edgeset++;        }        else if(flag[bian[count].u] && !flag[bian[count].v])/*v未加入,u已经加入*/        {            w+=bian[count].weight;            flag[bian[count].v]=true;            nodeset[bian[count].v]=nodeset[bian[count].u];            edgeset++;        }        else if(!flag[bian[count].u] && !flag[bian[count].v])            /*两个都未加入*/        {            w+=bian[count].weight;            flag[bian[count].u]=true;            flag[bian[count].v]=true;            nodeset[bian[count].u]=nodeset[bian[count].v];            edgeset++;        }        else if(nodeset[bian[count].u]!=nodeset[bian[count].v])/*如果两个加入集合,判断加入集合是否相同,相同说明形成环,跳出此次循环,转向下一次。*/        {                                                      /*否则将两个集合合并*/            w+=bian[count].weight;            edgeset++;            int tmp=nodeset[bian[count].v];            for(i=0;i<n;i++)                if(nodeset[i]=tmp)                nodeset[i]=nodeset[bian[count].u];        }        count++;                          /*转向次小边,进行下一次判断*/    }    cout<<"该图权值是:"<<w;              /*输出权值*/}int main(){    int i,j;    for(i=0; i<Vnum; i++)        for(j=0; j<Vnum; j++)            quan[i][j]=MAX;    GraphTp g;    creat(&g);    cout<<endl;    Kruskal(g.vexnum,quan);    return 0;}/*测试数据:6 10         //有向图的顶点数,边数0 1 2 3 4 5  //顶点数据0 1 6        //边数据0 2 10 3 51 2 51 4 32 3 52 4 62 5 44 5 63 5 2*/
0 0
原创粉丝点击