SRM 581 D2 L3:TreeUnionDiv2,Floyd算法

题目来源:http://community.topcoder.com//stat?c=problem_statement&pm=12587&rd=15501


这道题目开始以为是要在无向图中判断环,而且要找出环的大小,后来看了解析之后才发现原来使用一个Floyd算法就搞定了,因为题目中加了很多限制,并不真的需要在一个任意的无向图中求 指定大小的环的数量。生成所有的排列组合可以使用C++ STL提供的std::next_permutation 算法,非C++使用backtrack,具体实现可以参考解析


代码如下:

 

#include <algorithm>

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>

#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>

using namespace std;


/*************** Program Begin **********************/

int disA[9][9], disB[9][9];
int P[9];
const int INF = 1000;
class TreeUnionDiv2 {
public:
    int maximumCycles(vector <string> tree1, vector <string> tree2, int K) {
	int res = 0;
	int vex = tree1.size();
	for (int i = 0; i < 9; i++) {
		P[i] = i;
	}
	for (int i = 0; i < vex; i++) {
		for (int j = 0; j < vex; j++) {
			if ('X' == tree1[i][j]) {
				disA[i][j] = 1;
			} else {
				disA[i][j] = INF;
			}
			if ('X' == tree2[i][j]) {
				disB[i][j] = 1;
			} else {
				disB[i][j] = INF;
			}
		}
	}

	for (int k = 0; k < vex; k++) {
		for (int i = 0; i < vex; i++) {
			for (int j = 0; j < vex; j++){  
				if ( disA[i][j] > disA[i][k] + disA[k][j] ) {
					disA[i][j] = disA[i][k] + disA[k][j];
				}
				if ( disB[i][j] > disB[i][k] + disB[k][j] ) {
					disB[i][j] = disB[i][k] + disB[k][j];
				}
			}
		}
	}

	do {
		int c = 0;
		for (int i = 0; i < vex; i++) {
			for (int j = i+1; j < vex; j++) {
				if (disA[i][j] + disB[ P[i] ][ P[j] ] + 2 == K) {
					++c;
				}
			}
		}
		res = max(res, c);
	} while (next_permutation(P, P + vex));

	return res;
    }
};

/************** Program End ************************/

 

下面为使用 backtrack 实现的全部排列组合:

 

// This recursive function's only duty is to generate all the possible
// permutations P[]. 
void backtrack(int i)
{
    if (i == N-1) {
        //found a permutation, remember the best number of cycles:
        best = std::max(best, countCycles() );
    } else {
        for (int j=i; j<N; j++) {
            // Place P[j] in position i, move P[i] to P[j]:
            std::swap( P[i], P[j] );
            // Continue the backtracking search:
            backtrack(i+1);
            // Restore the positions of P[i] and P[j]:
            std::swap( P[j], P[i] );
        }
    }
}


 

 

 

posted on 2013-08-09 23:21  you Richer  阅读(183)  评论(0编辑  收藏  举报