/******************************************************* Problem - Building Teams Solution by - Sean Falconer Algorithm: Graph Coloring with at most 4 colors. This can be done with backtracking. Need to try all color combinations on the graph. The trick is to use the graph represented by the clique relationships, rather than the students. There can be up to 1000 students, which is too many to backtrack on, so just ignore the student information and work with the cliques. *******************************************************/ #include #include #include #include using namespace std; #define MAX 31 #define COLORS 4 int G[MAX][MAX], x[MAX], N, M; // x[k] is assigned the lowest color available that // does not conflict with it's adjacencies void nextValue(int k, int & colors) { while(1) { x[k] = (x[k] + 1) % (colors + 1); if(!x[k]) return; int j; for(j = 1; j <= N; j++) { if(G[k][j] && (x[k] == x[j])) break; } if(j == N+1) return; } } // color the graph, storing node colors in the array x int colorGraph(int k, int & colors) { while(1) { // assign a color to x[k] nextValue(k, colors); // couldn't assign a color, can't color the graph if(!x[k]) return -1; // finished coloring everything in the graph if(k == N) { // find and return the largest color used int largest = INT_MIN; for(int i = 1; i <= N; i++) { if(x[i] > largest) largest = x[i]; } return largest; } else { int r = colorGraph(k+1, colors); if(r != -1) return r; } } } // adds cliques to my vector and returns the index of the given clique int addClique(vector & cliques, string & s) { int i; for(i = 1; i < cliques.size(); i++) { if(cliques[i] == s) return i; if(cliques[i] == "") break; } cliques[i] = s; return i; } int main() { int T; ifstream cin("F.in"); cin >> T; for(int i = 0; i < T; i++) { cin >> N >> M; string s, s2; vector cliques(N+1); // initialize my adjacency graph and colors for(int j = 0; j <= N; j++) { x[j] = 0; for(int k = 0; k <= N; k++) G[j][k] = 0; } // read in the clique information for(int j = 1; j <= N; j++) { cin >> s; int i1 = addClique(cliques, s); int D; cin >> D; for(int k = 0; k < D; k++) { cin >> s; int i2 = addClique(cliques, s); G[i1][i2] = 1; G[i2][i1] = 1; } } // read in student information, ignore it for(int j = 0; j < M; j++) cin >> s >> s2; int colors; for(int j = 1; j <= COLORS; j++) { // color the graph colors = colorGraph(1, j); if(colors != -1) break; for(int k = 0; k <= N; k++) x[k] = 0; } cout << "Case " << i+1 << ": "; if(colors != -1) cout << colors << " team(s)" << endl; else cout << "Need more teams" << endl; } return 0; }