maximum clique 最大团

最大团模板
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#define out(v) cout << #v << ": " << (v) << endl
#define MP(X,Y) make_pair(X,Y)
using namespace std;
typedef long long LL;

// maximum clique
// tested: hdu3585, zju1492, pku1129
// paper: A Fast Algorithm For The Maximum Clique Problem
const int MAXN = 27;
int n;
bool G[MAXN][MAXN]; // indexed from one, adjacency matrix
int list[MAXN][MAXN], degree[MAXN], behide[MAXN];
int found, curmax;

void sortdegree() {
	for (int i = 1; i <= n; i++) {
		int k = i;
		for (int j = i + 1; j <= n; j++)
			if (degree[j] < degree[k]) k = j;
		if (k != i) {
			swap(degree[i], degree[k]);
			for (int t = 1; t <= n; t++) swap(G[i][t], G[k][t]);
			for (int t = 1; t <= n; t++) swap(G[t][i], G[t][k]);
		}
	}
}
void dfs(int d){
	if (d - 1 > curmax) { found = 1; return; };
	int i, j;
	for (int i = 1; i < list[d - 1][0] - curmax + d; i++)
		if (!found && d + behide[list[d - 1][i] + 1] > curmax
		 &&	(list[d - 1][0] == i || d + behide[list[d - 1][i + 1]] > curmax)) {
			for (j = i + 1, list[d][0] = 0; j <= list[d - 1][0]; j++)
				if (G[list[d - 1][j]][list[d - 1][i]])
					list[d][++list[d][0]] = list[d - 1][j];
				if (list[d][0] == 0 || d + behide[list[d][1]] > curmax)
					dfs(d + 1);
		}
}
int solve() {
	for (int i = 1; i <= n; i++) {
		degree[i] = 0;
		for (int j = 1; j <= n; j++) degree[i] += G[i][j];
	}
	sortdegree(); behide[n + 1] = 0; behide[n] = 1;
	for (int i = n - 1; i > 0; i--) {
		curmax = behide[i + 1]; found = list[1][0] = 0;
		for (int j = i + 1; j <= n; j++)
			if (G[j][i]) list[1][++list[1][0]] = j;
		dfs(2); behide[i] = curmax + found;
	}
	return behide[1];
}

int set[MAXN];
int main()
{
	char line[30];
	while (scanf("%d", &n), n != 0)
	{
		memset(G, false, sizeof(G));
		for (int i = 1; i <= n; ++i)
		{
			scanf("%s", line);
			int u = line[0] - 'A' + 1;
			set[i] = u;
			for (int j = 2; line[j]; ++j)
				G[u][line[j] - 'A' + 1] = true;
		}
		int cnt = solve();
		printf("%d channel%s needed.\n", cnt, cnt == 1 ? "" : "s");
		for (int i = 1; i <= list[1][0]; ++i)
			cout << char('A' + list[1][i] - 1) << " ";
		cout << endl;
	}

	return 0;
}

你可能感兴趣的:(J#)