Pagini recente » Cod sursa (job #1541462) | Cod sursa (job #2317873) | Cod sursa (job #3163918) | Cod sursa (job #2689402) | Cod sursa (job #2905463)
import java.io.*;
import java.util.*;
import java.util.stream.IntStream;
public class Main {
public static class BonusSolver {
private final List<Book> books;
private final List<Object> maxMatch;
private final HashMap<Book, Category> assignedCategory;
private final HashMap<Category, Book> assignedBook;
private final HashMap<Book, Boolean> visited;
public BonusSolver(List<Book> books) {
this.books = books;
this.visited = new HashMap<>();
this.assignedBook = new HashMap<>();
this.assignedCategory = new HashMap<>();
this.maxMatch = new LinkedList<>();
}
private boolean getMatch(Book book) {
if (visited.get(book)) {
return false;
}
visited.put(book, true);
for (int i = 0; i < book.getNumberOfCategories(); ++i) {
if (!assignedBook.containsKey(book.getCategory(i))) {
assignedCategory.put(book, book.getCategory(i));
assignedBook.put(book.getCategory(i), book);
return true;
}
}
for (int i = 0; i < book.getNumberOfCategories(); ++i) {
if (getMatch(assignedBook.get(book.getCategory(i)))) {
assignedCategory.put(book, book.getCategory(i));
assignedBook.put(book.getCategory(i), book);
return true;
}
}
return false;
}
public void runHopcroftKarp() {
boolean change = true;
while (change) {
change = false;
for (Book book : books) {
visited.put(book, false);
}
for (Book book : books) {
if (!assignedCategory.containsKey(book)) {
change |= getMatch(book);
}
}
visited.clear();
}
for (Book book : books) {
if (assignedCategory.containsKey(book)) {
maxMatch.add(book);
maxMatch.add(assignedCategory.get(book));
}
}
}
public List<Object> getMaxMatching() {
return maxMatch;
}
}
public static class Book {
private final Integer index;
private final List<Category> categories;
public Book(int index, String name) {
this.index = index;
this.categories = new LinkedList<>();
}
public Integer getIndex() {
return index;
}
public void addCategory(Category category) {
categories.add(category);
}
public int getNumberOfCategories() {
return categories.size();
}
public Category getCategory(int index) {
return categories.get(index);
}
}
public static class Category {
private final Integer index;
public Category(int index, String name) {
this.index = index;
}
public Integer getIndex() {
return index;
}
}
public static class Library {
private final List<Book> books;
private final List<Category> categories;
Library() {
books = new LinkedList<>();
categories = new ArrayList<>();
}
public void addBook(Book book) {
books.add(book);
}
public void addCategory(Category category) {
categories.add(category);
}
public Book getBook(int index) {
return books.get(index);
}
public Category getCategory(int index) {
return categories.get(index);
}
public void addLink(Book book, Category category) {
book.addCategory(category);
}
public List<Book> getBooks() {
return books;
}
}
public static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}
public static void main(String[] args) throws FileNotFoundException {
InputReader in = new InputReader(new FileInputStream("fmcm.in"));
PrintWriter out = new PrintWriter(new FileOutputStream("fmcm.out"));
Library library = new Library();
IntStream.rangeClosed(1, in.nextInt())
.mapToObj(i -> new Book(i, "B" + i))
.forEach(library::addBook);
IntStream.rangeClosed(1, in.nextInt())
.mapToObj(i -> new Category(i, "C" + i))
.forEach(library::addCategory);
int edges = in.nextInt();
for (; edges > 0; --edges) {
library.addLink(library.getBook(in.nextInt() - 1), library.getCategory(in.nextInt() - 1));
}
BonusSolver bonusSolver = new BonusSolver(library.getBooks());
bonusSolver.runHopcroftKarp();
List<Object> maxMatch = bonusSolver.getMaxMatching();
out.println(maxMatch.size() >> 1);
for (int i = 0; i < maxMatch.size(); i += 2) {
out.println(((Book) maxMatch.get(i)).getIndex() + " " + ((Category) maxMatch.get(i + 1)).getIndex());
}
out.close();
}
}