标签:tail UNC 输出 递归调用 最短路径 dfs 技术 queue names
大概题意:
假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论(即通过五个人就可以认识另外一个人)的结点占结点总数的百分比。
输入第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号节点。
标签:tail UNC 输出 递归调用 最短路径 dfs 技术 queue names
原文地址:https://www.cnblogs.com/acoccus/p/10711902.html