其他分享
首页 > 其他分享> > 06-图3 六度空间

06-图3 六度空间

作者:互联网

大概题意:

假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论(即通过五个人就可以认识另外一个人)的结点占结点总数的百分比。

输入格式:

输入第1行给出两个正整数,分别表示社交网络图的结点数N(1,表示人数)、边数M(≤,表示社交关系数)。随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个结点的编号(节点从1到N编号)。

输出格式:

对每个结点输出与该结点距离不超过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%
下面是根据老师讲的广度优先搜索。
#include <cstdio>
#include <stdlib.h>
#include <queue>
using namespace std;

const int MaxVertexNum = 1e4 + 2;
//setting the limit of probing depth
const int LmtDepth = 6;
int depth, Nv, Ne;
int count = 1, dfscount = 1;
int Visted[MaxVertexNum];

typedef int Vertex;

typedef struct AdjNode * PtrToAdjNode;
struct AdjNode {
    int Data;
    PtrToAdjNode Next;
};

typedef struct GNode * LGraph;
struct GNode {
    int Nv;
    long long Ne;
    PtrToAdjNode G[MaxVertexNum];
};
typedef struct ENode * Edge;
struct ENode {
    Vertex V1, V2;
};


LGraph createGraph(int Vnum);
LGraph buildGraph();
void insertEdge(LGraph G, Edge E);



LGraph createGraph(int VertexNum) {
    LGraph Graph = new GNode;
    Graph->Ne = 0;
    Graph->Nv = VertexNum;
    
    for (int i=1; i<=VertexNum; i++) {
        Graph->G[i] = NULL;
    }
    
    return Graph;
}

LGraph buildGraph() {
    scanf("%d", &Nv);
    
    LGraph Graph = createGraph(Nv);
    scanf( "%lld", &(Graph->Ne) );
    
    Edge Etmp = (Edge) malloc(sizeof(struct ENode));
    for(long long  i=1; i<=Graph->Ne; i++) {
        scanf("%d %d", &(Etmp->V1), &(Etmp->V2));
        insertEdge(Graph, Etmp);
    }
    return Graph;
}

void insertEdge(LGraph Graph, Edge E) {
    PtrToAdjNode newNode = new AdjNode;
    newNode->Data = E->V2;
    newNode->Next = Graph->G[E->V1];
    Graph->G[E->V1] = newNode;
    
    PtrToAdjNode newNode2 = new AdjNode;
    newNode2->Data = E->V1;
    newNode2->Next = Graph->G[E->V2];
    Graph->G[E->V2] = newNode2;
}

int DFS(LGraph Gph, Vertex V, int depth);
void calc_reset();

void SDS(LGraph G);
int BFS(Vertex V, LGraph G);

int main() {
    LGraph Graph = buildGraph();
    /*printf("BFS RESULT\n");
    SDS(Graph);
    */
    //printf("DFS RESULT\n");
    
    for (int i=1; i<=Nv; i++) {
        calc_reset();
        
        printf("%d: %.2f%%\n", i, (double) DFS(Graph, i, 0) / Nv * 100);
    }
    
    return 0;
}


int DFS(LGraph Gph, Vertex V, int depth ) {
    int count = 1;
    Visted[V] = 1;
    if(depth >= 6) return 1;
    
    PtrToAdjNode W = Gph->G[V];
    
    for(; W; W = W->Next) {
         if(!Visted[W->Data]){
            count += DFS(Gph, W->Data, depth+1);
            //Visted[W->Data] = 0;
         }
     }
    

    return count;
}



void calc_reset() {
    depth = 0;
    dfscount = 1;
    for (int i = 1; i<=Nv; i++) {
        Visted[i] = 0;
    }
    
}


void SDS(LGraph Graph) {
    int count;
    for (Vertex V=1; V<=Nv; V++) {
        calc_reset();
        count = BFS(V, Graph);
        printf("%d: %.2f%%\n", V, (double) count / Nv * 100);
    }
}

int BFS(Vertex V, LGraph Graph) {
    queue<int> Q;
    int count = 1;
    int level = 0, last = V, tail = V;
    
    Visted[V] = 1;
    Q.push(V);
    
    while (!Q.empty()) {
        V = Q.front();
        Q.pop();
        PtrToAdjNode E = new AdjNode;
        
        for (E = Graph->G[V]; E; E = E->Next) {
            if (!Visted[E->Data]) {
                Visted[E->Data] = 1;
                count++;
                Q.push(E->Data);
                tail = E->Data;
            }
        }
        
        if (V == last) {
            last = tail;
            level++;
        }
        
        if (level == LmtDepth) {
            break;
        }
    }
    return count;
    
}

原先自己写了一个DFS,限制探测深度为6,最后一个测试点通不过,纠结了一会儿。


BFS能确定最短路径,但是DFS不行,在递归调用的时候会封闭某些节点(Visted[W] = 1)导致可能原先能访问到的节点不能访问。如下图反例。

如果先深度探测到7,那就封闭了4号节点。

 







标签:结点,六度,06,struct,int,Graph,LGraph,空间,Data
来源: https://www.cnblogs.com/acoccus/p/10711902.html