Gửi bài giải
Điểm:
800 (OI)
Giới hạn thời gian:
2.0s
Giới hạn bộ nhớ:
256M
Input:
stdin
Output:
stdout
Tác giả:
Dạng bài
Ngôn ngữ cho phép
Ada, Assembly, Awk, Brain****, C, C#, C++, COBOL, D, Dart, F#, Forth, Fortran, Go, Groovy, Haskell, Intercal, Java, JS, Kotlin, Lisp, Lua, ObjC, OCaml, Pascal, Perl, PHP, Pike, Prolog, PyPy, Python, Racket, Ruby, Rust, Scala, Scheme, Scratch, Sed, Swift, TCL, Turing, VB, Zig
Buổi hòa nhạc của
Tuy nhiên một vài người họ đã không hài lòng và đã đề nghị đổi vị trí với nhau sao cho cặp đôi nào cũng được ngồi gần nhau. Một cặp đôi được gọi là ngồi gần nhau khi họ ngồi cạnh nhau cùng hàng hoặc ngồi cạnh nhau cùng cột.
Để đảm bảo trật tự cho buổi hòa nhạc bạn hãy giúp họ chọn ra số người ít nhất được đổi chỗ để cặp đôi nào cũng được ngồi gần nhau.
- Dòng đầu tiên chứa hai số nguyên
và là kích thước của khán đài. dòng tiếp theo mỗi dòng chứa số nguyên ( ), các cặp đôi được biểu thị bởi các số nguyên giống nhau.
- Gồm một dòng duy nhất là số người tối thiểu cần được đổi chỗ.
, .- Dữ liệu đảm bảo không có ai phải đi một mình.
- Subtask
: , . - Subtask
: Không có giới hạn gì thêm.
Copy
4 3
1 2 2
3 1 4
5 5 6
3 6 4
Copy
4
- Các vị trí cần đổi chỗ là
, , , .
Bình luận
include <iostream>
include <vector>
include <cstring>
include <algorithm>
define INF 1e9
const int MAXN = 80 * 80 + 5; int N, M; int grid[80][80]; int idx[80][80]; int n, m; std::vector<int> adj[MAXN]; int cost[MAXN][MAXN];
int lx[MAXN], ly[MAXN]; int slack[MAXN]; int match[MAXN]; bool visx[MAXN], visy[MAXN];
bool dfs(int x) { visx[x] = true; for (int y : adj[x]) { if (visy[y]) continue; int delta = lx[x] + ly[y] - cost[x][y]; if (delta == 0) { visy[y] = true; if (match[y] == -1 || dfs(match[y])) { match[y] = x; return true; } } else { slack[y] = std::min(slack[y], delta); } } return false; }
int KM() { memset(match, -1, sizeof(match)); memset(ly, 0, sizeof(ly)); for (int x = 0; x < n; ++x) { lx[x] = -INF; for (int y : adj[x]) { lx[x] = std::max(lx[x], cost[x][y]); } } for (int x = 0; x < n; ++x) { std::fill(slack, slack + m, INF); while (true) { memset(visx, 0, sizeof(visx)); memset(visy, 0, sizeof(visy)); if (dfs(x)) break; int d = INF; for (int y = 0; y < m; ++y) { if (!visy[y]) d = std::min(d, slack[y]); } for (int i = 0; i < n; ++i) { if (visx[i]) lx[i] -= d; } for (int y = 0; y < m; ++y) { if (visy[y]) ly[y] += d; else slack[y] -= d; } } } int result = 0; for (int y = 0; y < m; ++y) { if (match[y] != -1) { result += cost[match[y]][y]; } } return -result; }
int main() { std::ios::syncwithstdio(false); std::cin.tie(nullptr);
} code cho minhtriet
Xin sol bài này với mọi người :((
include <iostream>
include <vector>
include <cstring>
include <algorithm>
define INF 1e9
const int MAXN = 80 * 80 + 5; int N, M; int grid[80][80]; int idx[80][80]; int n, m; std::vector<int> adj[MAXN]; int cost[MAXN][MAXN];
int lx[MAXN], ly[MAXN]; int slack[MAXN]; int match[MAXN]; bool visx[MAXN], visy[MAXN];
bool dfs(int x) { visx[x] = true; for (int y : adj[x]) { if (visy[y]) continue; int delta = lx[x] + ly[y] - cost[x][y]; if (delta == 0) { visy[y] = true; if (match[y] == -1 || dfs(match[y])) { match[y] = x; return true; } } else { slack[y] = std::min(slack[y], delta); } } return false; }
int KM() { memset(match, -1, sizeof(match)); memset(ly, 0, sizeof(ly)); for (int x = 0; x < n; ++x) { lx[x] = -INF; for (int y : adj[x]) { lx[x] = std::max(lx[x], cost[x][y]); } } for (int x = 0; x < n; ++x) { std::fill(slack, slack + m, INF); while (true) { memset(visx, 0, sizeof(visx)); memset(visy, 0, sizeof(visy)); if (dfs(x)) break; int d = INF; for (int y = 0; y < m; ++y) { if (!visy[y]) d = std::min(d, slack[y]); } for (int i = 0; i < n; ++i) { if (visx[i]) lx[i] -= d; } for (int y = 0; y < m; ++y) { if (visy[y]) ly[y] += d; else slack[y] -= d; } } } int result = 0; for (int y = 0; y < m; ++y) { if (match[y] != -1) { result += cost[match[y]][y]; } } return -result; }
int main() { std::ios::syncwithstdio(false); std::cin.tie(nullptr);
} day la y tuong cua mik cho tham khao