有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,因此我需要找到更有效的解决方案。
答案 0 :(得分:1)
您可以创建包含所有数字的完整图形,并删除与输入对相对应的边。
在结果图中,每个hamiltonian path对应一个解决方案。因此,您需要一种算法来查找给定图形中的哈密顿路径数。
不幸的是,没有时间有效的解决方案。也就是说,您必须枚举所有可能的路径来计算它们。 因此,简而言之,寻找算法来计算汉密尔顿路径。
以下是一些讨论:
A so thread that discusses this exact problem
根据输入对的数量,可能更容易计算破坏条件的解决方案的数量。您可以从可能性总数(n!)中减去它,以获得您想要的答案。