使用前向星方法(应该是吧?我着实不确定这种我不知道从哪看到之后一直在用的存储方法究竟叫什么= =)存储的带权图,实现了通用的DFS和BFS算法,可以通过函数对象使用。
正好这两天复习算法,所以整理了一下。有些时候有这么一个模板还是挺方便的说。。
直接上代码了


1 struct ForwardStarWGraph; 2 struct Node; 3 4 struct CallbackFunctor 5 { 6 virtual bool shouldExtend(ForwardStarWGraph& graph, Node& toExtend) = 0; 7 virtual bool operator() (ForwardStarWGraph& graph, Node& curr) = 0; 8 }; 9 10 struct Node 11 { 12 int i; 13 int from; 14 int edge; 15 int totalWight; 16 vector<int> path; 17 }; 18 19 const int N = 20; // max vertex conut 20 const int M = N*N; // max edge count 21 22 struct ForwardStarWGraph 23 { 24 int to[M], nxt[M], head[N]; 25 int wight[M]; 26 int ecnt; 27 // Actual vertex number 28 int n; 29 30 void graphInit(int nn, int m) 31 { 32 ecnt = 0; 33 n = nn; 34 memset(head, -1, sizeof(head)); 35 } 36 37 // Add an edge, vertex counts from 0 38 void addEdge(int u, int v, int w) 39 { 40 to[ecnt] = v; 41 wight[ecnt] = w; 42 nxt[ecnt] = head[u]; 43 head[u] = ecnt; 44 ecnt++; 45 } 46 47 // Add an undirectional edge 48 void addBiEdge(int u, int v, int w) 49 { 50 addEdge(u, v, w); 51 addEdge(v, u, w); 52 } 53 54 int wightBetween(int a, int b) 55 { 56 if(a == b) 57 return 0; 58 for(int e = head[a]; e!= -1; e = nxt[e]) 59 { 60 if(to[e] == b) 61 return wight[e]; 62 } 63 return -1; 64 } 65 66 void bfs(CallbackFunctor& func) 67 { 68 queue<Node> Q; 69 70 Node tem; 71 tem.i = 0; 72 tem.from = -1; 73 tem.edge = -1; 74 tem.totalWight = 0; 75 tem.path.push_back(0); 76 Q.push(tem); 77 78 while(!Q.empty()) 79 { 80 Node t = Q.front(); Q.pop(); 81 82 func(*this, t); 83 84 for(int e = head[t.i]; e!= -1; e = nxt[e]) 85 { 86 if(to[e] == t.from) 87 continue; 88 Node t2; 89 t2.i = to[e]; 90 t2.from = t.i; 91 t2.edge = e; 92 t2.totalWight = t.totalWight + wight[e]; 93 t2.path = t.path; t2.path.push_back(t2.i); 94 if(func.shouldExtend(*this, t2)) 95 { 96 Q.push(t2); 97 } 98 } 99 } 100 } 101 102 void dfs(CallbackFunctor& func) 103 { 104 stack<Node> Q; 105 106 Node tem; 107 tem.i = 0; 108 tem.from = -1; 109 tem.edge = -1; 110 tem.totalWight = 0; 111 tem.path.push_back(0); 112 Q.push(tem); 113 114 while(!Q.empty()) 115 { 116 Node t = Q.top(); Q.pop(); 117 118 func(*this, t); 119 120 for(int e = head[t.i]; e!= -1; e = nxt[e]) 121 { 122 if(to[e] == t.from) 123 continue; 124 Node t2; 125 t2.i = to[e]; 126 t2.from = t.i; 127 t2.edge = e; 128 t2.totalWight = t.totalWight + wight[e]; 129 t2.path = t.path; t2.path.push_back(t2.i); 130 if(func.shouldExtend(*this, t2)) 131 { 132 Q.push(t2); 133 } 134 } 135 } 136 } 137 };
附带一个测试小程序


1 int n, m; 2 ForwardStarWGraph g; 3 4 struct Routine : CallbackFunctor 5 { 6 virtual bool shouldExtend (ForwardStarWGraph& graph, Node& toExtend) 7 { 8 return true;; 9 } 10 11 virtual bool operator() (ForwardStarWGraph& graph, Node& curr) 12 { 13 cout<<curr.i+1<<endl; 14 } 15 }; 16 17 int main() 18 { 19 #ifdef ACM_LOCAL 20 freopen("input.txt", "r", stdin); 21 //freopen("output.txt", "w", stdout); 22 #endif // ACM_LOCAL 23 while(scanf("%d %d", &n, &m) != EOF) 24 { 25 g.graphInit(n, m); 26 for(int i = 0; i!= m; i++) 27 { 28 int a, b, w; 29 scanf("%d%d%d", &a, &b, &w); 30 g.addBiEdge(a-1, b-1, w); 31 } 32 Routine routine; 33 g.bfs(routine); 34 } 35 36 37 #ifdef ACM_LOCAL 38 printf("Used time: %lf\n", clock() / (double) CLOCKS_PER_SEC); 39 #endif // ACM_LOCAL 40 return 0; 41 }