Pagini recente » Cod sursa (job #2863741) | Cod sursa (job #2863146) | Cod sursa (job #2920025) | Cod sursa (job #3286613) | Cod sursa (job #3278033)
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);
pw.close();
}
}