• Six Degree of Separation


    本博客的代码的思想和图片参考:好大学慕课浙江大学陈越老师、何钦铭老师的《数据结构》

    题目:

    六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。


    图1 六度空间示意图

    “六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。

    假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。

    输入格式:

    输入第1行给出两个正整数,分别表示社交网络图的结点数NNN(1<N≤1041<Nle 10^41<N104​​,表示人数)、边数MMM(≤33×Nle 33 imes N33×N,表示社交关系数)。随后的MMM行对应MMM条边,每行给出一对正整数,分别是该条边直接连通的两个结点的编号(节点从1到NNN编号)。

    输出格式:

    对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:(空格)百分比%”。

    输入样例:

    10 9
    1 2
    2 3
    3 4
    4 5
    5 6
    6 7
    7 8
    8 9
    9 10
    

    输出样例:

    1: 70.00%
    2: 80.00%
    3: 90.00%
    4: 100.00%
    5: 100.00%
    6: 100.00%
    7: 100.00%
    8: 90.00%
    9: 80.00%
    10: 70.00%
    

    We use two kinds of method to store the graph:adjacnet matrix and adjacnet table
    The code is followed:
      1 /*
      2  * sixDigreeSeparation.c
      3  *
      4  *  Created on: 2017年5月8日
      5  *      Author: ygh
      6  */
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 
     10 /*
     11  * Algorithm thought:
     12  * We easily know this question is BFS.
     13  * we  access the first level nodes, then access second level nodes
     14  * until we reach the sixth level.
     15  * We let every node to BFS until it reach the sixth level,then we record the total nodes M
     16  * it can reach, calculate the M/N(The total point the test data gives) .
     17  */
     18 
     19 #define MAX_VERTEX_MUM 10001
     20 typedef int vertex; /*vertex is the index of point in the graph*/
     21 typedef int dataType; /*dataType is the data type of vertex */
     22 typedef int weightType; /*The data type of weight  */
     23 
     24 /*
     25  * Define a data structure to edge
     26  */
     27 typedef struct eNode *ptrToENode;
     28 typedef struct eNode {
     29     vertex v1, v2;
     30     weightType wight;
     31 };
     32 typedef ptrToENode edge;
     33 
     34 /*
     35  * Define a data structure for adjacent table node
     36  */
     37 typedef struct adjNode *ptrToAdjNode;
     38 typedef struct adjNode {
     39     vertex adjVertex; /*The index of vertex in the graph*/
     40     weightType weight; /*the value of the weight*/
     41     ptrToAdjNode next; /*A point to point next node*/
     42 };
     43 
     44 /*
     45  * Define a data structure for adjacent table head point
     46  */
     47 typedef struct vNode *ptrToVNode;
     48 typedef struct vNode {
     49     dataType data; /*The value of every vertex,some times it will be ignore*/
     50     ptrToAdjNode head;/*The point to point the adjacent table first element*/
     51 } adjList[MAX_VERTEX_MUM];
     52 
     53 /*Define a data structure for graph*/
     54 typedef struct gNode *ptrToGNode;
     55 typedef struct gNode {
     56     int vertex_num;
     57     int edge_num;
     58     adjList g;
     59 };
     60 typedef ptrToGNode adjacentTableGraph; /*a graph show by adjacent table*/
     61 
     62 /*
     63  create a graph given the vertex number.
     64  @param vertexNum The verter number of the graph
     65  @return a graph with vertex but no any egdgs
     66  */
     67 ptrToGNode createGraph(int vertexNum) {
     68     vertex v;
     69     adjacentTableGraph graph = (adjacentTableGraph) malloc(
     70             sizeof(struct gNode));
     71     graph->vertex_num = vertexNum;
     72     graph->edge_num = 0;
     73     for (v = 1; v <= graph->vertex_num; v++) {
     74         graph->g[v].head = NULL;
     75     }
     76     return graph;
     77 }
     78 
     79 /*
     80  insert a edge to graph.We will distinct oriented graph and undirected graph
     81  The e->v1 and e->v2 are the vertexs' indexs in the adjacent table
     82  @param graph The graph you want to insert edge
     83  @param e The edge you want to insert the graph
     84  @param isOriented Whether the graph is oriented graph.If the graph is oriented
     85  we will set adjacent table graph[v1]->head=v2 and set graph[v1].head=v2
     86  otherwise we only set graph[v1].head=v2
     87  */
     88 void insertEdge(adjacentTableGraph graph, edge e, int isOriented) {
     89     ptrToAdjNode newNode;
     90     newNode = (ptrToAdjNode) malloc(sizeof(struct adjNode));
     91     newNode->adjVertex = e->v2;
     92     newNode->weight = e->wight;
     93     newNode->next = graph->g[e->v1].head;
     94     graph->g[e->v1].head = newNode;
     95     if (!isOriented) {
     96         newNode = (ptrToAdjNode) malloc(sizeof(struct adjNode));
     97         newNode->adjVertex = e->v1;
     98         newNode->weight = e->wight;
     99         newNode->next = graph->g[e->v2].head;
    100         graph->g[e->v2].head = newNode;
    101     }
    102 }
    103 
    104 adjacentTableGraph buildGraph() {
    105     adjacentTableGraph graph;
    106     edge e;
    107     vertex v;
    108     int vertex_num;
    109     scanf("%d", &vertex_num);
    110     graph = createGraph(vertex_num);
    111     scanf("%d", &(graph->edge_num));
    112     if (graph->edge_num) {
    113         e = (edge) malloc(sizeof(struct eNode));
    114         for (v = 0; v < graph->edge_num; v++) {
    115             scanf("%d %d", &e->v1, &e->v2);
    116             e->wight = 1;
    117             insertEdge(graph, e, 0);
    118         }
    119     }
    120     return graph;
    121 }
    122 
    123 /*==============================define a queue=====================================================*/
    124 /*define a list to store the element in the queue*/
    125 typedef vertex elementType;
    126 typedef struct node *pList;
    127 typedef struct node {
    128     elementType element;
    129     struct node *next;
    130 };
    131 
    132 /*define a queue to point the list*/
    133 typedef struct node2 *pQueue;
    134 typedef struct node2 {
    135     pList front; /*the front point to point the head of the list*/
    136     pList rear; /*the rear point to point the rear of of the list*/
    137 };
    138 
    139 /*create a empty list to store the queue element*/
    140 pList createEmptyList() {
    141     pList list;
    142     list = (pList) malloc(sizeof(struct node));
    143     list->next = NULL;
    144     return list;
    145 }
    146 /*create a empty queye*/
    147 pQueue createEmptyQueue() {
    148     pQueue queue = (pQueue) malloc(sizeof(struct node2));
    149     queue->front = NULL;
    150     queue->rear = NULL;
    151     return queue;
    152 }
    153 
    154 /*
    155  Wether the queue is empty
    156  @param queue The queue need to adjust
    157  @return If the queue is null,return 1 otherwise return 0
    158  */
    159 int isQueueEmpty(pQueue queue) {
    160     return (queue->front == NULL);
    161 }
    162 
    163 /*
    164  Add a element to a queue,If the queue is null,we will create a new queue
    165  @parama queue The queue we will add elememt to
    166  @prama element The element we will add to queue
    167  */
    168 void addQueue(pQueue queue, elementType element) {
    169     if (isQueueEmpty(queue)) {
    170         pList list = createEmptyList();
    171         list->element = element;
    172         queue->front = queue->rear = list;
    173     } else {
    174         pList newNode = (pList) malloc(sizeof(struct node));
    175         newNode->element = element;
    176         newNode->next = queue->rear->next;
    177         queue->rear->next = newNode;
    178         queue->rear = newNode;
    179     }
    180 }
    181 
    182 /*
    183  delete a element from a queue
    184  @param queue The queue will be deleted a element
    185  @return The element has been deleted
    186  */
    187 elementType deleteEleFromQueue(pQueue queue) {
    188     if (isQueueEmpty(queue)) {
    189         printf("the queue is empty,don't allow to delete elemet from it!");
    190     } else {
    191         pList oldNode = queue->front;
    192         elementType element = oldNode->element;
    193         if (queue->front == queue->rear) {
    194             queue->rear = queue->front = NULL;
    195         } else {
    196             queue->front = queue->front->next;
    197         }
    198         free(oldNode);
    199         return element;
    200     }
    201 }
    202 
    203 /*
    204  * Initialize a visited array that make them all to zero
    205  */
    206 void initVisited(adjacentTableGraph graph, int *visited) {
    207     int i;
    208     for (i = 0; i <= graph->vertex_num; i++) {
    209         visited[i] = 0;
    210     }
    211 }
    212 
    213 /*
    214  Breadth first search
    215  @param graph The graph stored by the adjacent table
    216  @param startPoint The point we start search
    217  @param visited A array to tag the elemeent whether has been visited
    218  */
    219 int BFS(adjacentTableGraph graph, vertex startPoint, int *visited) {
    220     ptrToAdjNode p;
    221     int count = 0;
    222     int level = 0;
    223     int last = startPoint, tail;
    224     visited[startPoint] = 1;
    225     count++;
    226     pQueue queue = createEmptyQueue();
    227     addQueue(queue, startPoint);
    228     while (!isQueueEmpty(queue)) {
    229         elementType element = deleteEleFromQueue(queue);
    230         for (p = graph->g[element].head; p; p = p->next) {
    231             if (visited[p->adjVertex] == 0) {
    232                 visited[p->adjVertex] = 1;
    233                 addQueue(queue, p->adjVertex);
    234                 count++;
    235                 tail = p->adjVertex;
    236             }
    237         }
    238         if (last == element) {
    239             level++;
    240             last = tail;
    241         }
    242         if (level == 6) {
    243             return count;
    244         }
    245     }
    246     return count;
    247 }
    248 
    249 /*
    250  *Prove the six degree of separation
    251  */
    252 void SDS(adjacentTableGraph graph) {
    253     vertex v;
    254     int count;
    255     int visited[graph->vertex_num+1];
    256     float result;
    257     for (v = 1; v <= graph->vertex_num; v++) {
    258         initVisited(graph, visited);
    259         count = BFS(graph, v, visited);
    260         result = (float)((float)count / graph->vertex_num)*100;
    261         printf("%d: %0.2f", v, result);
    262         printf("%%");
    263         printf("
    ");
    264     }
    265 }
    266 
    267 int main() {
    268     adjacentTableGraph graph = buildGraph();
    269     SDS(graph);
    270     return 0;
    271 }
    Adjacnet Table
      1 /*
      2  * sixDigreeSeparation.c
      3  *
      4  *  Created on: 2017年5月9日
      5  *      Author: ygh
      6  */
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 
     10 /*
     11  * Algorithm thought:
     12  * We easily know this question is BFS.
     13  * we  access the first level nodes, then access second level nodes
     14  * until we reach the sixth level.
     15  * We let every node to BFS until it reach the sixth level,then we record the total nodes M
     16  * it can reach, calculate the M/N(The total point the test data gives) .
     17  */
     18 
     19 #define MAX_VERTEX_NUM 10001 /*define the max number of the vertex*/
     20 #define INFINITY 65535     /*define double byte no negitive integer max number is 65535*/
     21 
     22 typedef int vertex; /*define the data type of the vertex*/
     23 typedef int weightType; /*define the data type of the weight*/
     24 typedef char dataType; /*define the data type of the vertex value*/
     25 
     26 /*define the data structure of the Edge*/
     27 typedef struct eNode *ptrToENode;
     28 typedef struct eNode {
     29     vertex v1, v2; /*two vertex between the edge <v1,v2>*/
     30     weightType weight; /*the value of the edge's weigth */
     31 };
     32 typedef ptrToENode edge;
     33 
     34 /*define the data structure of the graph*/
     35 typedef struct gNode *ptrToGNode;
     36 typedef struct gNode {
     37     int vertex_number; /*the number of the vertex*/
     38     int edge_nunber; /*the number of the edge*/
     39     weightType g[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; /*define the adjacent matrix of graph*/
     40     dataType data[MAX_VERTEX_NUM]; /*define the dataType array to store the value of vertex*/
     41 };
     42 typedef ptrToGNode adjacentMatrixGraph; /*a graph show by adjacent matrix*/
     43 
     44 /*
     45  create a graph given the vertex number.
     46  @param vertexNum The verter number of the graph
     47  @return a graph with vertex but no any egdgs
     48  */
     49 adjacentMatrixGraph createGraph(int vertexNum) {
     50     vertex v, w;
     51     adjacentMatrixGraph graph;
     52     graph = (adjacentMatrixGraph) malloc(sizeof(struct gNode));
     53     graph->vertex_number = vertexNum;
     54     graph->edge_nunber = 0;
     55     /*initialize the adjacent matrix*/
     56     for (v = 1; v <= graph->vertex_number; v++) {
     57         for (w = 1; w <= graph->vertex_number; w++) {
     58             graph->g[v][w] = 0;
     59         }
     60     }
     61 
     62     return graph;
     63 }
     64 
     65 /*
     66  insert a edge to graph.We will distinct oriented graph and undirected graph
     67  @param graph The graph you want to insert edge
     68  @param e The edge you want to insert the graph
     69  @param isOriented Whether the graph is oriented graph.If the graph is oriented
     70  we will set adjacent matrix [n][m]=[m][n]=edge's weight,else we only set
     71  the adjacent matrix [n][m]=edge's weight
     72  */
     73 void inserEdge(adjacentMatrixGraph graph, edge e, int isOriented) {
     74     graph->g[e->v1][e->v2] = e->weight;
     75     if (!isOriented) {
     76         graph->g[e->v2][e->v1] = e->weight;
     77     }
     78 }
     79 
     80 /*
     81  construct a graph according user's input
     82 
     83  @return a graph has been filled good
     84  */
     85 adjacentMatrixGraph buildGraph() {
     86     adjacentMatrixGraph graph;
     87     edge e;
     88     int vertex_num, i;
     89     scanf("%d", &vertex_num);
     90     graph = createGraph(vertex_num);
     91     scanf("%d", &(graph->edge_nunber));
     92     if (graph->edge_nunber) {
     93         e = (edge) malloc(sizeof(struct eNode));
     94         for (i = 0; i < graph->edge_nunber; i++) {
     95             scanf("%d %d", &e->v1, &e->v2);
     96             e->weight = 1;
     97             inserEdge(graph, e, 0);
     98         }
     99     }
    100 
    101     return graph;
    102 
    103 }
    104 
    105 /*=====================define a queue used BFS================================*/
    106 /*
    107  * The elementType is element which the following list store.
    108  */
    109 typedef int elementType;
    110 
    111 /*
    112  * Define a list to store the queue elements
    113  */
    114 typedef struct node1 *pList;
    115 typedef struct node1 {
    116     elementType element;
    117     struct node1 *next;
    118 };
    119 
    120 /*
    121  * Define a queue used to BFS
    122  */
    123 typedef struct node2 *pQueue;
    124 typedef struct node2 {
    125     pList font;
    126     pList rear;
    127 };
    128 
    129 /*
    130  * Create a empty list
    131  */
    132 pList createEmptyList() {
    133     pList list = (pList) malloc(sizeof(struct node1));
    134     list->next = NULL;
    135     return list;
    136 }
    137 
    138 /*
    139  * Create a empty queue
    140  */
    141 pQueue createEmptyQueue() {
    142     pQueue queue = (pQueue) malloc(sizeof(struct node2));
    143     queue->font = queue->rear = NULL;
    144     return queue;
    145 }
    146 
    147 /*
    148  * Whether the queue is empty
    149  */
    150 int isQueueEmpty(pQueue queue) {
    151     return (queue->font == NULL);
    152 }
    153 
    154 /*
    155  * Insert a element to a queue
    156  */
    157 void insertQueue(pQueue queue, elementType element) {
    158 
    159     if (isQueueEmpty(queue)) {
    160         pList list = createEmptyList();
    161         list->element = element;
    162         queue->font = queue->rear = list;
    163     } else {
    164         pList newNode = (pList) malloc(sizeof(struct node1));
    165         newNode->element = element;
    166         //newNode->next = queue->rear->next;
    167         queue->rear->next = newNode;
    168         queue->rear = newNode;
    169     }
    170 }
    171 
    172 elementType deleteElementQueue(pQueue queue) {
    173     if (isQueueEmpty(queue)) {
    174         return -1;
    175     } else {
    176         if (queue->font == queue->rear) {
    177             pList temp = queue->font;
    178             elementType elememt = temp->element;
    179             free(temp);
    180             queue->font = queue->rear = NULL;
    181             return elememt;
    182         } else {
    183             pList temp = queue->font;
    184             elementType elememt = temp->element;
    185             free(temp);
    186             queue->font = queue->font->next;
    187             return elememt;
    188         }
    189 
    190     }
    191 
    192 }
    193 
    194 /*
    195  *Breath first search a graph which store in form of adjacent matrix
    196  *@param graph The graph stored with adjacent matrix
    197  *@param startPoint The start point we start search
    198  *@param visited A array to tag whether element has been accessed
    199  */
    200 int BFS(adjacentMatrixGraph graph, vertex startPoint, int *visited) {
    201     vertex v, w;
    202     /*
    203      * count:to record the total nodes the start point can access
    204      * level:to record the level the current node accessed
    205      * tail:to record the every node's index, every access it will be flush
    206      * last:to record last lever latest accessed node,we can use it to
    207      *         let level add.
    208      */
    209     int count = 0;
    210     int level = 0, last = startPoint;
    211     int tail = last;
    212     pQueue queue = createEmptyQueue();
    213     count++;
    214     visited[startPoint] = 1;
    215     insertQueue(queue, startPoint);
    216     while (!isQueueEmpty(queue)) {
    217         w = deleteElementQueue(queue);
    218         for (v = 1; v <= graph->vertex_number; v++) {
    219             if (graph->g[w][v] != 0 && visited[v] == 0) {
    220                 visited[v] = 1;
    221                 insertQueue(queue, v);
    222                 tail = v;
    223                 count++;
    224             }
    225         }
    226         if (w == last) {
    227             level++;
    228             last = tail;
    229         }
    230 
    231         if (level == 6) {
    232             return count;
    233         }
    234     }
    235     return count;
    236 
    237 }
    238 
    239 /*
    240  * Initialize a visited array that make them all to zero
    241  */
    242 void initVisited(adjacentMatrixGraph graph, int *visited) {
    243     int i;
    244     for (i = 1; i <= graph->vertex_number; i++) {
    245         visited[i] = 0;
    246     }
    247 }
    248 
    249 /*
    250  *Prove the six degree of separation
    251  *@param graph A graph prepared
    252  */
    253 void SDS(adjacentMatrixGraph graph) {
    254     int visited[graph->vertex_number + 1];
    255     vertex v;
    256     int count;
    257     float result;
    258     for (v = 1; v <= graph->vertex_number; v++) {
    259         initVisited(graph, visited);
    260         count = BFS(graph, v, visited);
    261         result = (float) ((float) count / graph->vertex_number * 100);
    262         printf("%d: %0.2f", v, result);
    263         printf("%%");
    264         printf("
    ");
    265     }
    266 }
    267 
    268 int main() {
    269     adjacentMatrixGraph graph = buildGraph();
    270     SDS(graph);
    271     return 0;
    272 }
    Adjacnet Matrix

    From PTA test result,we find the adjacent matrix effective is more high than adjacent table.But the adjacent matrix take more memory.Is it use space

    to swap the time

    the test result is follow

  • 相关阅读:
    Java学习个人备忘录之继承
    Java学习个人备忘录之文档注释
    Java学习个人备忘录之数组工具类
    Java学习个人备忘录之关键字static
    Java学习个人备忘录之构造函数&this
    Java学习个人备忘录之面向对象概念
    Java学习个人备忘录之数组
    Java学习个人备忘录之入门基础
    hdoj1162-Eddy's picture(kruskal)
    hdoj1102-Constructing Roads(Kruskal)
  • 原文地址:https://www.cnblogs.com/yghjava/p/6832602.html
Copyright © 2020-2023  润新知