Hướng dẫn giải của Cặp ghép cực đại trên đồ thị hai phía


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

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;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.