Cod sursa(job #421310)

Utilizator CezarMocanCezar Mocan CezarMocan Data 21 martie 2010 13:13:30
Problema Copii Scor 40
Compilator cpp Status done
Runda Algoritmiada 2010, Runda 4, Clasele 9-10 Marime 2.25 kb
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <map>
#define maxN 12

using namespace std;

int n, mat[maxN][maxN];
int i, j, groups;
char ch;
int comb[maxN], asoc[maxN], np[maxN], viz[maxN];
int what_gr[maxN];
int vec[maxN], viz_marc[maxN];
vector <pair <int, int> > curr;
vector <int> gr[maxN];
long long sol;
map <vector <pair <int, int> >, bool> fost;

void back_asoc(int groups, int k) {
	int i, j, ok, nrg;
	if (k == n - groups) {
		for (i = 1; i <= n; i++)
			gr[i].clear();

		np[0] = 0;
		for (i = 1; i <= n; i++)
			if (!viz[i]) 
				np[++np[0]] = i;
			
		for (i = 1; i <= groups; i++) {
			gr[i].push_back(comb[i]);
			what_gr[comb[i]] = i;
		}
		for (i = 1; i <= n - groups; i++) {
			gr[asoc[i]].push_back(np[i]);
			what_gr[np[i]] = asoc[i];
		}

		for (i = 1; i <= groups; i++)
			sort(gr[i].begin(), gr[i].end());
	
		nrg = 0;
		curr.clear();
		for (i = 1; i <= n; i++) {
			if (gr[what_gr[i]][0] == i) {
				nrg++;
				for (j = 0; j < gr[what_gr[i]].size(); j++)
					curr.push_back(make_pair(nrg, gr[what_gr[i]][j]));
			}
		}

		if (fost[curr] == 1)
			return;
		fost[curr] = 1;
		
		ok = 1;
		for (i = 1; i <= groups; i++) {
			memset(vec, 0, sizeof(vec));
			for (j = 0; j < gr[i].size(); j++)
				for (k = 1; k <= n; k++)
					if (mat[gr[i][j]][k] == 1)
						vec[what_gr[k]] = 1;
			
			for (j = 1; j <= groups; j++) {
				if (vec[j] == 0 && j != i) {
					ok = 0;
					return;
				}
			}
		}

/*		for (i = 0; i < curr.size(); i++)
			fprintf(stderr, "(%d %d)  ", curr[i].first, curr[i].second);
		fprintf(stderr, "\n");*/
		sol += ok;
	}
	else {
		for (i = 1; i <= groups; i++) {
			asoc[k + 1] = i;
			back_asoc(groups, k + 1);
		}
	}
}

void back_comb(int groups, int k) {
	int i;
	if (k == groups) {
		back_asoc(groups, 0);
//		fprintf(stderr, "\n");
	}
	else {
		for (i = comb[k] + 1; i <= n; i++) {
			comb[k + 1] = i;
			viz[i] = 1;
			back_comb(groups, k + 1);
			viz[i] = 0;
		}
	}

}

int main() {
	freopen("copii.in", "r", stdin);
	freopen("copii.out", "w", stdout);

	scanf("%d", &n);

	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++) {
			scanf(" %c ", &ch);
			mat[i][j] = ch - '0';
		}

	for (groups = 2; groups <= n; groups++) {
		back_comb(groups, 0);
//		fprintf(stderr, "\n");
	}

	printf("%lld\n", sol);


	return 0;
}