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] );

        }

    }

}


 

 

 

你可能感兴趣的:(UNION)