Cod sursa(job #3278032)

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

public class Main {

    static class Pair {
        int node;
        int flow;
        public Pair(int node, int flow) {
            this.node = node;
            this.flow = flow;
        }
    }

    static class Edge {
        int from, to;
        public Edge(int from, int to) {
            this.from = from;
            this.to = to;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Edge edge = (Edge) o;
            return from == edge.from && to == edge.to;
        }

        @Override
        public int hashCode() {
            return Objects.hash(from, to);
        }
    }

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

    public static int bfs(int source, int sink, int[] parent) {
        Arrays.fill(parent, -1);
        parent[source] = -2;
        Queue<Pair> q = new LinkedList<>();
        q.add(new Pair(source, Integer.MAX_VALUE));

        while (!q.isEmpty()) {
            Pair cur = q.poll();
            int node = cur.node;
            int flow = cur.flow;

            for (int next : adj.get(node)) {
                if (parent[next] == -1 && cap[node][next] > 0) {
                    parent[next] = node;
                    int newFlow = Math.min(flow, cap[node][next]);
                    if (next == sink) {
                        return newFlow;
                    }
                    q.add(new Pair(next, newFlow));
                }
            }
        }
        return 0;
    }

    public static int maxFlow(int source, int sink) {
        int flow = 0;
        int[] parent = new int[n + m + 2];
        int newFlow;

        while ((newFlow = bfs(source, sink, parent)) > 0) {
            flow += newFlow;
            int cur = sink;

            while (cur != source) {
                int prev = parent[cur];
                cap[prev][cur] -= newFlow;
                cap[cur][prev] += newFlow;
                cur = prev;
            }
        }
        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 int[sink + 1][sink + 1];
        adj = new ArrayList<>();
        for (int i = 0; i <= sink; i++) {
            adj.add(new ArrayList<>());
        }
        List<Edge> hold = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            cap[source][i] = 1;
            adj.get(source).add(i);
            adj.get(i).add(source);
        }
        for (int i = 1; i <= m; i++) {
            cap[n + i][sink] = 1;
            adj.get(n + i).add(sink);
            adj.get(sink).add(n + i);
        }
        for (int i = 0; i < k; i++) {
            x = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(x.nextToken());
            int b = Integer.parseInt(x.nextToken());
            b += n;

            adj.get(a).add(b);
            adj.get(b).add(a);
            cap[a][b] = 1;
            hold.add(new Edge(a, b));
        }
        br.close();
        int maxMatching = maxFlow(source, sink);
        int maxEdges = 0;
        StringBuilder printEdges = new StringBuilder();
        Set<Edge> cuplaj = new HashSet<>();
        for (Edge edge : hold) {
            if (cap[edge.from][edge.to] == 0) {
                maxEdges++;
                cuplaj.add(new Edge(edge.from, edge.to - n));
            }
        }
        pw.println(cuplaj.size());
        for(Edge e: cuplaj) {
            printEdges.append(e.from).append(" ").append(e.to).append("\n");
        }
        pw.print(printEdges);
    }
}