Editorial for Cặp ghép cực đại trên đồ thị hai phía
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
#include<iostream> #include<algorithm> #define fr(a,b,c) for (a=b;a<=c;a++) #define frr(a,b,c) for (a=b;a>=c;a--) using namespace std; int m,n,a[1111],b[1111],d[1111],c[1111][1111],t; int dfs(int x) { int i; fr(i,1,n) if (c[x][i] && !d[i]) { t=i; d[i]=x; if (!b[i] || dfs(b[i])) return 1; } return 0; } int find() { int i; fr(i,1,n) d[i]=0; fr(i,1,m) if (!a[i]) if (dfs(i)) return 1; return 0; } void inc() { int x,y; while (t) { x=d[t]; y=t; t=a[x]; a[x]=y; b[y]=x; } } int main() { int i,x,y,k,re=0; cin >> m >> n >> k; while (k--) { scanf("%d%d",&x,&y); c[x][y]=1; } while (find()) inc(); fr(i,1,m) if (a[i]) re++; cout << re << endl; return 0; }
Code mẫu của happyboy99x
#include<bits/stdc++.h> using namespace std; #define TR(v,i) for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i) #define mset(a,i) memset(a, i, sizeof a) const int N = 1000; int nx, ny, my[N], vy[N]; vector<int> g[N]; void enter() { cin >> nx >> ny; int m; cin >> m; for(int i = 0; i < m; ++i) { int u, v; cin >> u >> v; g[u-1].push_back(v-1); } } bool dfs(int s) { TR(g[s], u) if(!vy[*u]) { vy[*u] = true; if(my[*u] == -1 || dfs(my[*u])) return my[*u] = s, true; } return false; } int maxMatch() { mset(my, -1); int res = 0; for(int i = 0; mset(vy, 0), i < nx; ++i) if(dfs(i)) ++res; return res; } int main() { ios::sync_with_stdio(false); enter(); cout << maxMatch() << '\n'; return 0; }
Code mẫu của ladpro98
#include <bits/stdc++.h> const int N = 1010; using namespace std; int matchX[N], matchY[N], Q[N], T[N]; int m, n, e; vector<int> a[N]; int BFS() { int l = 1, r = 0, i, u, v; for(i = 1; i <= m; i++) if (matchX[i] == 0) Q[++r] = i; for(i = 1; i <= n; i++) T[i] = 0; while (l <= r) { u = Q[l++]; for(i = 0; i < a[u].size(); i++) { v = a[u][i]; if (T[v] == 0) { T[v] = u; if (matchY[v] == 0) return v; else Q[++r] = matchY[v]; } } } return 0; } void Enlarge(int y) { int next, x; for(; y; y = next) { x = T[y]; next = matchX[x]; matchX[x] = y; matchY[y] = x; } } int main() { scanf("%d %d %d", &m, &n, &e); int i, u, v; for(i = 1; i <= e; i++) { scanf("%d %d", &u, &v); a[u].push_back(v); } while (i = BFS()) Enlarge(i); int res = 0; for(i = 1; i <= m; i++) if (matchX[i] != 0) res++; printf("%d\n", res); }
Code mẫu của RR
const MAXN=1011; type list=^node; node=record u:longint; next:list; end; procedure add(u:longint; var a:list); var p:list; begin new(p); p^.u:=u; p^.next:=a; a:=p; end; var n,m,k,u,v,x,y:longint; ke:array[1..MAXN] of list; matchX,matchY,trace,queue:array[1..MAXN] of longint; function findPath(x:longint):longint; var u,v,first,last:longint; p:list; begin fillchar(trace,sizeof(trace),0); first:=1; last:=1; queue[1]:=x; while first<=last do begin u:=queue[first]; inc(first); p:=ke[u]; while p<>nil do begin v:=p^.u; p:=p^.next; if (trace[v]=0) and (matchY[v]<>u) then begin trace[v]:=u; if matchY[v]=0 then exit(v); inc(last); queue[last]:=matchY[v]; end; end; end; exit(0); end; procedure enlarge(y:longint); var x,next:longint; begin while y<>0 do begin x:=trace[y]; next:=matchX[x]; matchX[x]:=y; matchY[y]:=x; y:=next; end; end; begin read(n,m,k); for k:=1 to k do begin read(u,v); add(v,ke[u]); end; for x:=1 to n do begin y:=findPath(x); enlarge(y); end; y:=0; for x:=1 to n do if matchX[x]<>0 then inc(y); writeln(y); end.
Code mẫu của hieult
#include<cstdio> #include<cmath> #include<math.h> #include<cstring> #include<cstdlib> #include<cassert> #include<ctime> #include<algorithm> #include<iterator> #include<iostream> #include<cctype> #include<string> #include<vector> #include<map> #include<set> #include<queue> #include<list> #define fi first #define se second #define PB push_back #define MP make_pair #define ep 0.00001 #define oo 111111111 #define mod 1000000007 #define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++) #define rep(i, n) for(int i = 0; i < n; i++) #define FOR(i, a, b) for(int i = a; i <= b; i++) #define FORD(i, a, b) for(int i = a; i >= b; i--) //#define g 9.81 double const PI=4*atan(1.0); using namespace std; typedef pair<int, int> II; typedef vector<int> VI; typedef vector<II> VII; typedef vector<VI> VVI; typedef vector<VII> VVII; typedef long long ll; void OPEN(){ freopen("A.in","r",stdin); freopen("A.out","w",stdout); } // Dinic #define maxn 50011 #define maxe 150111 struct HopcroftKarp{ int nx, ny, E, adj[maxe], next[maxe], last[maxn], matx[maxn], maty[maxn], que[maxn], level[maxn], run[maxn]; void init(int _nx, int _ny){ nx = _nx; ny = _ny; E = 0; FOR(x, 1, nx) last[x] = -1, matx[x] = -1; FOR(y, 1, ny) maty[y] = -1; } void add(int x, int y){ adj[E] = y; next[E] = last[x]; last[x] = E++; } bool bfs(){ bool found = false; int size = 0; FOR(x, 1, nx){ if(matx[x] != -1) level[x] = -1; else{ level[x] = 0; que[size++] = x; } } rep(i, size){ for(int x = que[i], e = last[x]; e != -1; e = next[e]){ int y = adj[e]; if(maty[y] == -1) found = true; else if(level[maty[y]] == -1){ level[maty[y]] = level[x] + 1; que[size++] = maty[y]; } } } return found; } int dfs(int x){ for(int &e = run[x]; e != -1; e = next[e]){ int y = adj[e]; if(maty[y] == -1 || (level[maty[y]] == level[x] + 1 && dfs(maty[y]))){ maty[y] = x; matx[x] = y; return 1; } } return 0; } int maxMatching(){ int total = 0; while(bfs()){ FOR(x, 1, nx) run[x] = last[x]; FOR(x, 1, nx) if(matx[x] == -1) total += dfs(x); } return total; } } hopkarp; int main(){ //OPEN(); int n, m, x, y, k; scanf("%d %d %d", &n, &m, &k); hopkarp.init(n, m); while(scanf("%d %d", &x, &y) > 0){ hopkarp.add(x, y); } printf("%d\n", hopkarp.maxMatching()); /* FOR(x, 1, n){ int y = hopkarp.matx[x]; if(y != -1) printf("%d %d\n", x, y); } */ }
Code mẫu của ll931110
program NKBM; const input = ''; output = ''; maxn = 1000; var a: array[1..maxn,1..maxn] of boolean; mx,my: array[1..maxn] of integer; trace,queue: array[1..maxn] of integer; front,rear: integer; m,n,k: integer; procedure init; var f: text; i,u,v: integer; begin fillchar(a, sizeof(a), false); assign(f, input); reset(f); readln(f, m, n, k); for i := 1 to k do begin readln(f, u, v); a[u,v] := true; end; close(f); end; procedure push(x: integer); begin inc(rear); queue[rear] := x; end; function FindPath: integer; var i,j: integer; begin fillchar(trace, sizeof(trace), 0); front := 1; rear := 0; for i := 1 to m do if mx[i] = 0 then push(i); while front <= rear do begin i := queue[front]; inc(front); for j := 1 to n do if (trace[j] = 0) and a[i,j] and (mx[i] <> j) then begin trace[j] := i; if my[j] = 0 then exit(j); push(my[j]); end; end; FindPath := 0; end; procedure Enlarge(x: integer); var y,z: integer; begin repeat y := trace[x]; z := mx[y]; mx[y] := x; my[x] := y; x := z; until x = 0; end; procedure solve; var fin: integer; begin repeat fin := FindPath; if fin <> 0 then Enlarge(fin); until fin = 0; end; procedure printresult; var f: text; i,c: integer; begin c := 0; for i := 1 to m do if mx[i] <> 0 then inc(c); assign(f, output); rewrite(f); writeln(f, c); close(f); end; begin init; solve; printresult; end.
Code mẫu của skyvn97
#include<bits/stdc++.h> #define MAX 1111 using namespace std; vector<int> gx[MAX]; int matx[MAX]; int maty[MAX]; int tx[MAX]; int ty[MAX]; int m,n; queue<int> q; void loadgraph(void) { int i,u,v,p; scanf("%d",&m); scanf("%d",&n); scanf("%d",&p); for (i=1;i<=p;i=i+1) { scanf("%d",&u); scanf("%d",&v); gx[u].push_back(v); } } int findway(const int &s) { memset(tx,0,sizeof tx); memset(ty,0,sizeof ty); while (!q.empty()) q.pop(); q.push(s); int i,p,v; while (!q.empty()) { p=q.front();q.pop(); for (i=0;i<gx[p].size();i=i+1) { v=gx[p][i]; if (ty[v]==0 && matx[p]!=v) { ty[v]=p; if (maty[v]==0) return (v); else { tx[maty[v]]=v; q.push(maty[v]); } } } } return (0); } void enlarge(const int &f) { int u,v; u=ty[f]; while (u!=0) { v=tx[u]; matx[u]=0; maty[v]=0; u=ty[v]; } v=f; u=ty[f]; while (u!=0) { matx[u]=v; maty[v]=u; v=tx[u]; u=ty[v]; } } void maxmatching(void) { memset(matx,0,sizeof matx); memset(maty,0,sizeof maty); int i,t; bool cont; for (i=1;i<=m;i=i+1) { t=findway(i); if (t>0) enlarge(t); } } void print(void) { int i,c=0; for (i=1;i<=m;i=i+1) c=c+(matx[i]!=0); printf("%d\n",c); } int main(void) { //freopen("tmp.txt","r",stdin); loadgraph(); maxmatching(); print(); return 0; }
Code mẫu của khuc_tuan
#include <iostream> #include <cstdio> using namespace std; int m, n, sc; bool a[1111][1111], vs[1111]; int x[1111], y[1111]; bool tim(int i) { if(vs[i]) return false; vs[i] = true; for(int j=1;j<=n;++j) if(a[i][j]) { if(y[j]==0) { x[i] = j; y[j] = i; return true; } if(tim(y[j])) { x[i] = j; y[j] = i; return true; } } return false; } int main() { int u, v, socap=0; scanf("%d%d%d", &m, &n, &sc); for(int i=0;i<sc;++i) { scanf("%d%d", &u, &v); a[u][v] = true; } for(int i=1;i<=m;++i) { memset( vs, 0, sizeof(vs)); if(tim(i)) ++socap; } cout << socap << endl; //system("pause"); return 0; }
Comments