Untitled
unknown
java
4 years ago
12 kB
11
Indexable
import java.io.*;
public class Main {
public static int noOfDivaOneRoles = 0;
public static int noOfDivaTwoRoles = 0;
public static int d1Index = 0;
public static int d2Index = 0;
public static int superIndex = 1;
public static int actorsUsed = 0; // Antal skådespelare som fått roller
public static boolean localMinima = false;
public static boolean swapMade = true;
public static int iSwap = 0;
public static int jSwap = 0;
public static void main(String args[]) throws FileNotFoundException {
// InputStream is = new FileInputStream("testinput.txt");
Kattio io = new Kattio(System.in, System.out);
// Kattio io = new Kattio(is, System.out);
int n = io.getInt(); // Antal roller i problemet.
int s = io.getInt(); // Antal scener i problemet.
int k = io.getInt(); // Antal skådespelare i problemet.
int rolesActors[][] = new int[n][k + 1];
int scenesRoles[][] = new int[s][n + 1];
int rolePartners[][] = new int[n + 1][(n * n) + 1];
int divaOneRoles[] = new int[n];
int divaTwoRoles[] = new int[n];
int usedActors[] = new int[n];
int sol[][] = new int[n][n + 2]; // Lösningsarray.
// Initialize number of roles to 0.
for (int i = 0; i < n + 1; i++) {
rolePartners[i][0] = 0;
}
// Fyll 2d array med alla roller och vilka skådisar som kan spela respektive
// roll.
int available = 0;
for (int i = 0; i < n; i++) {
available = io.getInt();
rolesActors[i][0] = available;
// System.out.print("roleActors[" + i + "][0]: " + rolesActors[i][0] + " ");
for (int j = 1; j <= available; j++) {
rolesActors[i][j] = io.getInt();
// System.out.print("roleActors[" + i + "][" + j + "]: " + rolesActors[i][j] + "
// ");
if (rolesActors[i][j] == 1) {
divaOneRoles[noOfDivaOneRoles] = i + 1;
noOfDivaOneRoles++;
} else if (rolesActors[i][j] == 2) {
divaTwoRoles[noOfDivaTwoRoles] = i + 1;
noOfDivaTwoRoles++;
}
}
}
// Fyll 2d array med alla scener och vilka roller som är i respektive scen.
for (int i = 0; i < s; i++) {
int incr = 0;
available = io.getInt();
scenesRoles[i][0] = available;
for (int j = 1; j <= available; j++) {
scenesRoles[i][j] = io.getInt();
}
for (int p = 1; p <= scenesRoles[i][0]; p++) {
for (int e = 1; e <= scenesRoles[i][0]; e++) {
rolePartners[scenesRoles[i][p]][0] += 1;
incr = rolePartners[scenesRoles[i][p]][0];
rolePartners[scenesRoles[i][p]][incr] = scenesRoles[i][e];
}
}
}
int d1d2[] = new int[2];
d1d2 = getDivas(divaOneRoles, divaTwoRoles);
// This could go bad if no solution exists but we naively
// do it this way because the lab says there always is a solution
while (checkRoleScenes(d1d2, rolePartners)) {
d1d2 = getDivas(divaOneRoles, divaTwoRoles);
}
sol = insertActor(d1d2[0] - 1, 1, 0, sol);
sol = insertActor(d1d2[1] - 1, 2, 1, sol);
usedActors[0] = 1;
usedActors[1] = 2;
actorsUsed += 2;
int roleIndex = 2;
int superActor = k + 1;
boolean found = false;
// Create starting graph.
for (int i = 0; i < n; i++) {
if (d1d2[0] == i + 1 || d1d2[1] == i + 1) {
continue;
}
for (int j = 1; j < rolesActors[i].length; j++) {
if (!checkTaken(rolesActors[i][j], usedActors)) {
usedActors[roleIndex] = rolesActors[i][j];
actorsUsed++;
found = true;
sol = insertActor(i, rolesActors[i][j], roleIndex, sol);
break;
}
}
if (!found) {
usedActors[roleIndex] = superActor;
sol = insertActor(i, superActor, roleIndex, sol);
superActor++;
actorsUsed++;
}
roleIndex++;
found = false;
}
int i = 0;
while (swapMade) {
while (!localMinima && i != 150) {
sol = optimizeLocal(sol, rolesActors, scenesRoles, d1d2, k, superActor, rolePartners);
i++;
}
sol = swapTwoActors(sol, d1d2, k, n, rolePartners, rolesActors);
}
System.out.println(actorsUsed);
printSol(sol);
io.close();
}
private static int[][] optimizeLocal(int[][] sol, int[][] rolesActors, int[][] scenesRoles, int[] d1d2, int k,
int superActor, int[][] rolePartners) {
int[] r1r2 = new int[2];
int localSuperIndex = superIndex;
int rn = 0;
boolean check = true;
boolean localFlag = true;
for (int i = 0; i < sol.length; i++) {
if (sol[i][0] == 0) {
continue;
}
if (sol[i][2] != d1d2[0] && sol[i][2] != d1d2[1]) {
if (sol[i][0] > k) {
continue;
}
for (int j = 0; j < superActor; j++) {
rn = getSuper(sol, k);
if (rn == 0) {
continue;
}
r1r2[1] = sol[rn][2];
if (!checkRolePossible(sol[i][0], r1r2[1], rolesActors)) {
continue;
}
for (int e = 0; e < sol[i][1]; e++) {
r1r2[0] = sol[i][e + 2];
check = checkRoleScenes(r1r2, rolePartners);
if (check) {
break;
}
}
if (!check) {
sol[i][1] += 1;
sol[i][sol[i][1] + 1] = sol[rn][2];
sol[rn][0] = sol[rn][1] = sol[rn][2] = 0;
actorsUsed--;
localSuperIndex = superIndex;
localFlag = false;
break;
}
}
if (check) {
superIndex = 1;
}
check = true;
}
}
if (localFlag == true) {
localMinima = true;
}
return sol;
}
private static boolean checkValid(int[][] sol, int i, int k, int[] d1d2) {
if (sol[i][0] == 0) {
return true;
}
if (sol[i][2] == d1d2[0] || sol[i][2] == d1d2[1]) {
return true;
}
if (sol[i][0] > k) {
return true;
}
if (sol[i][1] != 1) {
return true;
}
return false;
}
private static int[][] swapTwoActors(int[][] sol, int[] d1d2, int k, int n, int[][] rolePartners,
int[][] rolesActors) {
swapMade = false;
int[] r1r2 = new int[2];
boolean check = true;
for (int i = iSwap; i < sol.length; i++) {
if (checkValid(sol, i, k, d1d2)) {
iSwap++;
continue;
}
iSwap++;
for (int j = jSwap + 1; j < sol.length; j++) {
jSwap++;
if (checkValid(sol, j, k, d1d2)) {
continue;
}
r1r2[0] = sol[i][2];
r1r2[1] = sol[j][2];
if (!checkRolePossible(sol[i][0], r1r2[1], rolesActors)) {
continue;
}
if (!checkRolePossible(sol[j][0], r1r2[0], rolesActors)) {
continue;
}
check = checkRoleScenes(r1r2, rolePartners);
if (!check) {
sol[i][2] = r1r2[1];
sol[j][2] = r1r2[0];
swapMade = true;
break;
}
}
if (swapMade) {
break;
}
}
return sol;
}
private static boolean checkRolePossible(int actor, int role, int[][] ra) {
for (int i = 1; i < ra[role - 1].length; i++) {
if (ra[role - 1][i] == actor) {
return true;
}
}
return false;
}
private static int getSuper(int[][] sol, int k) {
for (int i = 0; i < sol.length; i++) {
if (sol[i][0] == k + superIndex) {
superIndex++;
return i;
}
}
return 0;
}
private static void printSol(int[][] sol) {
for (int i = 0; i < sol.length; i++) {
for (int j = 0; j < sol[i].length; j++) {
if (sol[i][j] == 0) {
break;
}
System.out.print(sol[i][j] + " ");
}
System.out.println("");
}
}
private static int[][] insertActor(int role, int actor, int roleIndex, int[][] sol) {
sol[roleIndex][0] = actor;
sol[roleIndex][1] = 1;
sol[roleIndex][2] = role + 1;
return sol;
}
private static boolean checkTaken(int actor, int[] usedActors) {
for (int i = 0; i < usedActors.length; i++) {
if (usedActors[i] == actor) {
return true;
}
}
return false;
}
private static boolean checkRoleScenes(int[] r1r2, int[][] rolePartners) {
int max = 0;
int role = 0;
int role2 = 0;
if (rolePartners[r1r2[0]][0] > rolePartners[r1r2[1]][0]) {
max = rolePartners[r1r2[1]][0];
role = r1r2[1];
role2 = r1r2[0];
} else {
max = rolePartners[r1r2[0]][0];
role = r1r2[0];
role2 = r1r2[1];
}
for (int i = 1; i <= max; i++) {
if (rolePartners[role][i] == role2) {
return true;
}
if (rolePartners[role][i] == 0) {
return false;
}
}
return false;
}
private static boolean checkDivaScenes(int[] d1d2, int[][] sr) {
boolean dOneInScene = false;
boolean dTwoInScene = false;
if (d1d2[0] == 0 || d1d2[1] == 0) {
return true;
}
for (int i = 0; i < sr.length; i++) {
for (int j = 1; j <= sr[i][0]; j++) {
if (sr[i][j] == d1d2[0]) {
dOneInScene = true;
} else if (sr[i][j] == d1d2[1]) {
dTwoInScene = true;
}
if (dOneInScene == true && dTwoInScene == true) {
return true;
}
}
dOneInScene = dTwoInScene = false;
}
return false;
}
private static int[] getDivas(int[] d1r, int[] d2r) {
int[] d1d2 = new int[2];
for (int i = d1Index; i < noOfDivaOneRoles; i++) {
for (int j = d2Index; j < noOfDivaTwoRoles; j++) {
if (d1r[i] != d2r[j]) {
d1d2[0] = d1r[i];
d1d2[1] = d2r[j];
d2Index++;
return d1d2;
}
d2Index++;
}
d2Index = 0;
d1Index++;
}
return d1d2;
}
}Editor is loading...