N个整数的排列有多少个K对不能相邻的数字?

时间:2014-10-11 16:54:16

标签: c++ algorithm permutation combinatorics

有N个整数{1,2,...,N}和K个有序数字对(A,B); A!= B; A,B <= N.没有对是相同的(例如(2,4)不能多次输入)。相同的元素可以出现在许多对中。我必须编写一个带有算法的C ++程序来查找所有N个整数的排列数,其中任何对中没有B跟随它的A.注意对(A,B)!=(B,A)。

示例:

n = 5
k = 4
k1: (2, 3)
k2: (1, 4)
k3: (3, 2)
k4: (2, 4)

This perm. is OK: 4 1 3 5 2
This is not OK: 3 1 4 2 5

这是我的暴力解决方案,递归检查每种可能性:

#include <iostream>
using namespace std;

int n;
bool conflict[1000][1000];
bool visited[1000];
int result = 0;
int currentlength = 0;

void count(int a) {
    visited[a] = true;
    currentlength++;
    if (currentlength == n) {
        result++;
        visited[a] = false;
        currentlength--;
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!visited[i] && !conflict[a][i]) {
            count(i);
        }
    }
    visited[a] = false;
    currentlength--;
}

int main()
{
    int k;
    cin >> n >> k;
    for (int i = 0; i < k; i++) {
        int a, b;
        cin >> a >> b;
        conflict[a][b] = 1;
    }
    for (int i = 1; i <= n; i++) {
        count(i);
    }
    cout << result << endl;
    return 0;
}

N和K分别达到1000000和100000,因此我需要找到更有效的解决方案。

1 个答案:

答案 0 :(得分:1)

您可以创建包含所有数字的完整图形,并删除与输入对相对应的边。

在结果图中,每个hamiltonian path对应一个解决方案。因此,您需要一种算法来查找给定图形中的哈密顿路径数。

不幸的是,没有时间有效的解决方案。也就是说,您必须枚举所有可能的路径来计算它们。 因此,简而言之,寻找算法来计算汉密尔顿路径。

以下是一些讨论:

A so thread that discusses this exact problem

wolfram link


根据输入对的数量,可能更容易计算破坏条件的解决方案的数量。您可以从可能性总数(n!)中减去它,以获得您想要的答案。