zoukankan      html  css  js  c++  java
  • TCO14 2C L2: CliqueGraph,graph theory, clique

    称号: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
    ", (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 ************************/
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    python-字典
    C#公历转农历算法
    GridView控件显示图片
    SQLite DBHelp
    面向服务体系结构:适用于敏捷的系统
    针对 .NET 框架的安全编码指南
    Microsoft .NET Pet Shop 4
    C#.NET数据库访问类DBHelper
    Emgu CV 高斯建模
    .NET代码编写规范 整理
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4890354.html
Copyright © 2011-2022 走看看