称号:http://community.topcoder.com/stat?c=problem_statement&pm=13251&rd=16017
參考:http://apps.topcoder.com/wiki/display/tc/TCO+2014+Round+2C
假设用先计算出每条边,用邻接矩阵来表示图,然后用BFS或 Floyd-Warshall算法来计算距离的话。时间复杂度是O(N^3),会超时。依据题名的提示知要利用clique graph的性质来做。基本思想是在BFS的时候将一个clique看成一个总体。一旦訪问到clique中的一个点,则这个clique中全部点的距离都能够得到。算法描写叙述例如以下
for each source vertex s:
mark all vertices and all cliques as unvisited
start BFS from s
when processing a vertex v during the BFS:
for each unvisited clique C that contains v:
mark C as visited
use edges in C to discover new vertices
代码:
#include <algorithm> #include <functional> #include <numeric> #include <utility> #include <iostream> #include <sstream> #include <iomanip> #include <bitset> #include <string> #include <vector> #include <stack> #include <deque> #include <queue> #include <set> #include <map> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <cstring> #include <ctime> #include <climits> using namespace std; #define CHECKTIME() printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC) typedef pair<int, int> pii; typedef long long llong; typedef pair<llong, llong> pll; #define mkp make_pair /*************** Program Begin **********************/ bool visited_vertex[5001]; bool visited_clique[5001]; class CliqueGraph { public: long long calcSum(int N, vector <int> V, vector <int> sizes) { long long res = 0; vector <int> S(sizes.size() + 1); S[0] = 0; for (int i = 0; i < sizes.size(); i++) { S[i + 1] += S[i] + sizes[i]; } vector <vector<int>> cliques(sizes.size()); // clique i 包括的点 vector <vector<int>> vcliques(N); // 包括点v的cliques for (int i = 0; i < sizes.size(); i++) { for (int j = S[i]; j < S[i + 1]; j++) { cliques[i].push_back(V[j]); vcliques[ V[j] ].push_back(i); } } for (int src = 0; src < N; src++) { vector <int> D(N, 123456789); D[src] = 0; memset(visited_vertex, 0, sizeof(visited_vertex)); memset(visited_clique, 0, sizeof(visited_clique)); queue <int> Q; Q.push(src); visited_vertex[src] = true; while (!Q.empty()) { int v = Q.front(); Q.pop(); // 更新全部包括v的cliques中的全部点 for (int i = 0; i < vcliques[v].size(); i++) { int c = vcliques[v][i]; // 包括v的cliques if (visited_clique[c]) { continue; } visited_clique[c] = true; for (int j = 0; j < cliques[c].size(); j++) { int u = cliques[c][j]; // clique c z中的的点 if (visited_vertex[u]) { continue; } visited_vertex[u] = true; D[u] = D[v] + 1; Q.push(u); } } } for (int i = 0; i < N; i++) { res += D[i]; } } return res / 2; }; }; /************** Program End ************************/
版权声明:本文博主原创文章,博客,未经同意不得转载。
时间: 2024-12-10 23:58:38