zoukankan      html  css  js  c++  java
  • 06-图3. 六度空间 (30)

    数据有1万个,邻接矩阵挂了,所以只能套邻接表。第一次直接是套的模板,搜索过程也是参考教材指导书上的实现。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #include<stdlib.h>
    using namespace std;
    #define  MaxVertexNum  1024
    
    typedef  unsigned long  VertexType;
    typedef  struct  node    /* 边表结点 */
    {
        VertexType AdjV;            /* 邻接点域 */
        struct  node  *Next;  /* 指向下一个邻接点的指针域 */
    } EdgeNode;
    
    typedef  struct  Vnode       /* 顶点表结点 */
    {
        int vis;
        double percent;
        EdgeNode  *FirstEdge; /* 边表头指针 */
    } VertexNode;
    
    typedef VertexNode AdjList[ MaxVertexNum ];
    typedef  struct
    {
        AdjList  adjlist;    /* 邻接表 */
        unsigned long int  n, e;               /* 顶点数和边数 */
    } ALGraph;  /*ALGraph是以邻接表方式存储的图类型 */
    
    typedef struct queuenode
    {
        unsigned long int v;
        int level;
    };
    
    queue<queuenode>q;
    void bfs(ALGraph *G,unsigned long int st)
    {
        G->adjlist[st].vis=1;
        int cnt=1;
        EdgeNode *egde;
        queuenode qe;
        while(!q.empty()) q.pop();
        qe.v=st;
        qe.level=0;
        q.push(qe);
        while(!q.empty())
        {
            qe=q.front();
            q.pop();
            for(egde=G->adjlist[qe.v].FirstEdge; egde; egde=egde->Next)
            {
                if(!G->adjlist[egde->AdjV].vis)
                {
                    G->adjlist[egde->AdjV].vis=1;
                    cnt++;
                    if(++qe.level<6)
                    {
                        //printf("%ld %ld
    ",st+1,egde->AdjV+1);
                        qe.v=egde->AdjV;
                        q.push(qe);
                    }
                    qe.level--;
                }
            }
        }
        G->adjlist[st].percent=(double)cnt/(double)G->n*100.0;
        //printf("%ld: %.2f%%
    ",st+1,G->adjlist[st].percent);
    }
    
    int main()
    {
        unsigned long int i,j,k;
        ALGraph *G=(ALGraph*)malloc(sizeof( ALGraph));
        EdgeNode *edge;
        while(~scanf("%d%d",&(G->n),&(G->e)))
        {
            for ( i=0; i < G->n; i++ )     /* 建立有n个顶点的顶点表 */
            {
                G->adjlist[i].vis=0;
                G->adjlist[i].percent=0.0;
                G->adjlist[i].FirstEdge = NULL; /* 顶点的边表头指针设为空 */
            }
            for ( k=0; k < G->e; k++ )    /* 建立边表 */
            {
                scanf( "%d%d", &i, &j); /* 读入边<vi,vj>的顶点对应序号*/
                edge = (EdgeNode*)malloc(sizeof(EdgeNode)); /* 生成新边结点edge */
                edge->AdjV = j-1; /* 邻接点序号为j */
                edge->Next = G->adjlist[i-1].FirstEdge;
                /* 将新边表结点edge插入到顶点vi的边表头部 */
                G->adjlist[i-1].FirstEdge = edge;
    
                edge = (EdgeNode*)malloc(sizeof(EdgeNode)); /* 生成新边结点edge */
                edge->AdjV = i-1; /* 邻接点序号为j */
                edge->Next = G->adjlist[j-1].FirstEdge;
                /* 将新边表结点edge插入到顶点vi的边表头部 */
                G->adjlist[j-1].FirstEdge = edge;
            }
            for(i=0L; i<G->n; i++)
            {
                bfs(G,i);
                printf("%ld: %.2f%%
    ",i+1,G->adjlist[i].percent);
                for ( j=0L; j < G->n; j++ )     /* 建立有n个顶点的顶点表 */
                {
                    G->adjlist[j].vis=0;
                }
            }
        }
        return 0;
    }

    教材上的参考代码

    #include<stdio.h>
    #include<stdlib.h>
    
    #define SIX 6
    #define  MaxVertexNum  1000     /* 最大顶点数 */
    
    typedef unsigned long  VertexType;    /* 顶点用无符号长整数表示 */
    typedef  struct  node{          /* 边表结点 */
        VertexType AdjV;              /* 邻接点域 */
        struct  node  *Next;          /* 指向下一个邻接点的指针域 */
      /* 若要表示边上的权值信息,则应增加一个数据域Weight */
    } EdgeNode;        
    
    typedef unsigned long  VertexType;    /* 顶点用无符号长整数表示 */
    typedef  struct  Vnode{       /* 顶点表结点 */
        char   Visited;              /* 顶点域,这里用于标记该结点是否已经访问 */
        double  Percent;              /* 用于记录距离不超过SIX的结点百分比 */
        EdgeNode  *FirstEdge;       /* 边表头指针 */
    } VertexNode;
    
    typedef  VertexNode  AdjList[ MaxVertexNum ];
    /* AdjList是邻接表类型 */
    typedef  struct{  
        AdjList  adjlist;          /* 邻接表 */
        unsigned long int  n, e;  /* 顶点数和边数 */
    } ALGraph;                   /* ALGraph是以邻接表方式存储的图类型 */
    
    typedef struct Element { 
        VertexType v;        /* 结点编号 */
        int Layer;           /* BFS的层次 */
    } QElementType;
    typedef struct Node{
        QElementType  Data;
        struct Node  *Next;
    }QNode; 
    typedef  struct {              /* 链队列结构  */
        QNode  *rear;              /* 指向队尾结点 */
        QNode  *front;             /* 指向队头结点 */
    } LinkQueue;
    
    void Initialize(LinkQueue  *PtrQ)
    {
        PtrQ->rear = PtrQ->front = NULL;
    }
    
    int IsEmptyQ(LinkQueue  *PtrQ)
    {
        return PtrQ->front == NULL ;
    }
    
    void AddQ ( LinkQueue  *PtrQ, QElementType item )
    {   
        QNode *cell = (QNode *)malloc(sizeof(QNode));/* 申请一个结点空间  */
    
        cell->Data = item; 
        cell->Next = NULL;
        if  ( IsEmptyQ(PtrQ) )  /* 若队列空,头尾是同一个元素 */
            PtrQ->front = PtrQ->rear = cell;
        else
        { /* 否则新元素添加到尾部 */
            PtrQ->rear->Next = cell;
            PtrQ->rear = cell;
        }
    }
    
    QElementType DeleteQ ( LinkQueue  *PtrQ )
    {   QNode  *FrontCell; 
        QElementType FrontElem;
    
        if  ( PtrQ->front == NULL) {
            printf("队列空");
            exit(0);
        } 
        FrontCell = PtrQ->front;
        if ( PtrQ->front == PtrQ->rear) /* 若队列只有一个元素 */
            PtrQ->front = PtrQ->rear = NULL; /* 删除后队列置为空 */
        else                     
            PtrQ->front = PtrQ->front->Next;
        FrontElem = FrontCell->Data;
        free( FrontCell );  /* 释放被删除结点空间  */
        return  FrontElem;
    }
    
    void DestroyQueue( LinkQueue  Q )
    {
        QNode *cell ;
        while((cell = Q.front)){
            Q.front = Q.front->Next;
            free(cell);
        }
    }
    
    void CreateALGraph( ALGraph *G )
    {
        unsigned long int i,j,k;
        EdgeNode *edge;
    
        scanf( "%ld %ld", &(G->n), &(G->e) );      /* 读入顶点数和边数 */ 
        for ( i=0; i < G->n; i++ ) {        /* 建立有n个顶点的顶点表 */
            G->adjlist[i].Visited = 0;      /* 记录该结点是否已经访问 */
            G->adjlist[i].Percent = 0.0;    /* 距离不超过SIX的结点百分比 */
            G->adjlist[i].FirstEdge = NULL; /* 顶点的边表头指针设为空 */
        }
        for ( k=0; k < G->e; k++ ){   /* 建立边表 */
            scanf( "%ld %ld", &i, &j); /* 读入边<vi,vj>的顶点对应序号*/
            edge = (EdgeNode*) malloc( sizeof( EdgeNode ) );
            /* 生成新边表结点edge,用来表示边(vi, vj) */
            edge->AdjV = j-1; /* 邻接点序号为j */
            /* 将新边表结点edge插入到顶点vi的边表头部 */
            edge->Next = G->adjlist[i-1].FirstEdge;
            G->adjlist[i-1].FirstEdge = edge;
            /* 因为是无向图,还要生成一个结点,用来表示边(vj, vi)  */
            edge = (EdgeNode*) malloc( sizeof( EdgeNode ) );
            edge->AdjV = i-1; /* 邻接点序号为i */
            /* 将新边表结点edge插入到顶点vj的边表头部 */
            edge->Next = G->adjlist[j-1].FirstEdge;
            G->adjlist[j-1].FirstEdge = edge;
        }
    }
    
    void  SixDegree_BFS( ALGraph *G , VertexType Start )
    {   /* 计算离节点Start的距离不超过SIX的节点百分比 */
        QElementType  qe;   
        LinkQueue  Q; 
        VertexType  v;
        EdgeNode *edge;
        unsigned long int VisitCount = 1;  /* 记录路径长度<=SIX的顶点数 */
    
        Initialize( &Q );     /* 置空的队列Q */
         G->adjlist[Start].Visited = 1; 
        qe.v = Start; qe.Layer = 0;   /* 起点算0层 */
        AddQ( &Q, qe );                  /* qe入队列 */
        while ( !IsEmptyQ(&Q) ) {      /* 队列非空循环 */
            qe = DeleteQ(&Q); v = qe.v; 
            for( edge=G->adjlist[v].FirstEdge; edge; edge=edge->Next )
                if ( !G->adjlist[edge->AdjV].Visited )
                /* 若edge->AdjV是v的尚未访问的邻接顶点 */
                {    
                    G->adjlist[edge->AdjV].Visited = 1; 
                    /* 将其记为六度以内的顶点 */
                    VisitCount++ ;        /* 增加路径长度<=SIX的顶点数 */
                    if(++qe.Layer < SIX) /* 仅将六度以内的顶点再进队 */
                    {    qe.v = edge->AdjV;   
                        AddQ(&Q, qe);
                    }
                    qe.Layer--;   /* 恢复qe的层数 */
                } /* 结束if,for */
        } /* 结束while循环 */
        DestroyQueue( Q );
        G->adjlist[Start].Percent = 100.0 * (double)VisitCount / (double)G->n;
    }
    
    int main()
    {
        VertexType i,j;
        ALGraph *G = (ALGraph *)malloc( sizeof(ALGraph) );
        CreateALGraph( G );
        for(i=0L; i<G->n; i++)
        {    
            SixDegree_BFS( G, i );/*计算离节点i的距离不超过SIX的节点百分比 */
            printf("%ld: %.2f%%
    ", i+1, G->adjlist[i].Percent);
            for ( j=0; j < G->n; j++ )         /* 工作空间初始化 */
                G->adjlist[j].Visited = 0;     /* 重置标记所有结点未经访问 */
        }    
        return 0;
    }

    版权声明:本文为博主原创文章,未经博主允许不得转载。http://xiang578.top/

  • 相关阅读:
    cf D. Vessels
    cf C. Hamburgers
    zoj 3758 Singles' Day
    zoj 3777 Problem Arrangement
    zoj 3778 Talented Chef
    hdu 5087 Revenge of LIS II
    zoj 3785 What day is that day?
    zoj 3787 Access System
    判断给定图是否存在合法拓扑排序
    树-堆结构练习——合并果子之哈夫曼树
  • 原文地址:https://www.cnblogs.com/xryz/p/4848008.html
Copyright © 2011-2022 走看看