Cod sursa(job #3278039)

Utilizator pifaDumitru Andrei Denis pifa Data 18 februarie 2025 16:56:05
Problema Cuplaj maxim in graf bipartit Scor 30
Compilator java Status done
Runda Arhiva educationala Marime 3.17 kb
import java.util.*;
import java.io.*;

public class Main {

    static List<List<Integer>> adj;
    static int n, m, k;
    static Map<Integer, Map<Integer, Integer>> cap;

    public static int bfs(int source, int sink, int[] parent) {
        Arrays.fill(parent, -1);
        parent[source] = -2;
        Queue<Integer> q = new LinkedList<>();
        q.add(source);
        while (!q.isEmpty()) {
            int node = q.poll();
            for (int next : adj.get(node)) {
                if (parent[next] == -1 && cap.getOrDefault(node, new HashMap<>()).getOrDefault(next, 0) > 0) {
                    parent[next] = node;
                    if (next == sink) return 1;
                    q.add(next);
                }
            }
        }
        return 0;
    }

    public static int maxFlow(int source, int sink) {
        int flow = 0;
        int[] parent = new int[n + m + 2];
        while (bfs(source, sink, parent) > 0) {
            int cur = sink;
            while (cur != source) {
                int prev = parent[cur];
                cap.get(prev).put(cur, cap.get(prev).get(cur) - 1);
                cap.get(cur).put(prev, cap.getOrDefault(cur, new HashMap<>()).getOrDefault(prev, 0) + 1);
                cur = prev;
            }
            flow++;
        }
        return flow;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("cuplaj.in"));
        PrintWriter pw = new PrintWriter(new FileWriter("cuplaj.out"));
        StringTokenizer x = new StringTokenizer(br.readLine());
        n = Integer.parseInt(x.nextToken());
        m = Integer.parseInt(x.nextToken());
        k = Integer.parseInt(x.nextToken());
        int source = 0, sink = n + m + 1;
        cap = new HashMap<>();
        adj = new ArrayList<>();
        for (int i = 0; i <= sink; i++) {
            adj.add(new ArrayList<>());
            cap.put(i, new HashMap<>());
        }
        for (int i = 1; i <= n; i++) {
            adj.get(source).add(i);
            adj.get(i).add(source);
            cap.get(source).put(i, 1);
        }
        for (int i = 1; i <= m; i++) {
            adj.get(n + i).add(sink);
            adj.get(sink).add(n + i);
            cap.get(n + i).put(sink, 1);
        }
        Set<int[]> edges = new HashSet<>();
        for (int i = 0; i < k; i++) {
            x = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(x.nextToken());
            int b = Integer.parseInt(x.nextToken()) + n;

            adj.get(a).add(b);
            adj.get(b).add(a);
            cap.get(a).put(b, 1);
            edges.add(new int[]{a, b});
        }
        br.close();
        int maxMatching = maxFlow(source, sink);
        Set<int[]> cuplaj = new HashSet<>();
        for (int[] edge : edges) {
            if (cap.get(edge[0]).get(edge[1]) == 0) {
                cuplaj.add(new int[]{edge[0], edge[1] - n});
            }
        }
        pw.println(cuplaj.size());
        for (int[] e : cuplaj) {
            pw.println(e[0] + " " + e[1]);
        }
        pw.flush();
        pw.close();
    }
}