Hướng dẫn giải của Giao lưu


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 happyboy99x

#include<bits/stdc++.h>
using namespace std;

#define TR(v,i) for(__typeof((v).begin())i=(v).begin();i!=(v).end();++i)
const int N = 255, INF = 1e9;
vector<pair<int, int> > g[4*N+2];
vector<int> c, f;
pair<int, int> res[N];
int n, m;

void addEdge(int u, int v, int lim) {
    g[u].push_back(make_pair(v, c.size()));
    g[v].push_back(make_pair(u, c.size()+1));
    c.push_back(lim); c.push_back(0);
    f.push_back(0); f.push_back(0);
}

void enter() {
    cin >> n >> m;
    for(int i = 0; i < m; ++i) addEdge(i, m+i, 1);
    string s; getline(cin, s);
    for(int i = 0; i < n; ++i) {
        getline(cin, s);
        stringstream inp (s);
        for(int x; inp >> x; --x, addEdge(2*m+i, x, 1));
        addEdge(2*(m+n), 2*m+i, 1);
    }
    for(int i = 0; i < n; ++i) {
        getline(cin, s);
        stringstream inp (s);
        for(int x; inp >> x; --x, addEdge(m+x, 2*m+n+i, 1));
        addEdge(2*m+n+i, 2*(m+n)+1, 1);
    }
}

void maxflow(int s, int t, int n) {
    while(true) {
        vector<pair<int, int> > tr (n, make_pair(INF, INF));
        tr[s] = make_pair(-1, -1);
        queue<int> q; q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            if(u == t) break;
            TR(g[u], it) {
                int v = it->first, e = it->second;
                if(c[e] - f[e] > 0 && tr[v].first == INF)
                    tr[v] = make_pair(u, e), q.push(v);
            }
        }
        if(tr[t].first == INF) break;
        int delta = INF;
        for(int u = tr[t].first, v = t; u != -1; v = u, u = tr[u].first)
            delta = min(delta, c[tr[v].second] - f[tr[v].second]);
        for(int u = tr[t].first, v = t; u != -1; v = u, u = tr[u].first) {
            f[tr[v].second] += delta;
            f[tr[v].second ^ 1] -= delta;
        }
    }
}

void trace() {
    fill(res, res+m, make_pair(-1, -1));
    for(int i = 0; i < m; ++i) TR(g[i], it) {
        int v = it->first, e = it->second;
        if(f[e] == -1) TR(g[m+i], it) {
            int v2 = it->first, e2 = it->second;
            if(f[e2] == 1) res[i] = make_pair((v-2*m)%n, (v2-2*m)%n);
        }
    }
    for(int i = 0; i < m; ++i)
        cout << res[i].first + 1 << ' ' << res[i].second + 1 << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    enter();
    maxflow(2*(m+n), 2*(m+n)+1, 2*(m+n+1));
    trace();
    return 0;
}

Code mẫu của ladpro98

#include <bits/stdc++.h>

const int N = 1111;
const int INF = int(1e9);

using namespace std;

int n, nProblem;

int contestant(int side, int id) {
  return n * side + id;
}

int problem(bool out, int id) {
  return n + n + nProblem * out + id;
}

struct edge {
  int u, v;
  int cap, flow;

  edge(int _u, int _v, int _c) {
    u = _u; v = _v; cap = _c;
    flow = 0;
  }
};

struct network {
  int n;
  int source, sink;
  int maxFlow;
  int T[N];
  vector<int> a[N];
  vector<edge> E;

  void addEdge(int u, int v, int c) {
    a[u].push_back(E.size()); //* forward
    a[v].push_back(E.size() + 1); //* reverse
    E.push_back(edge(u, v, c));
    E.push_back(edge(v, u, 0)); //* directed graph
  }

  bool findPath() {
    queue<int> Q;
    Q.push(source);
    for (int i = 1; i <= n; ++i)
      T[i] = 0;
    while (!Q.empty()) {
      int u = Q.front(); Q.pop();
      for (int id: a[u]) {
        int v = E[id].v;
        if (T[v] == 0 && E[id].cap > E[id].flow) {
          T[v] = id;
          if (v == sink) return 1;
          Q.push(v);
        }
      }
    }
    return 0;
  }

  void incFlow() {
    int delta = INF;
    for (int v = sink, u = T[v]; v != source; v = E[u].u, u = T[v])
      delta = min(delta, E[u].cap - E[u].flow);
    for (int v = sink, u = T[v]; v != source; v = E[u].u, u = T[v])
      E[u].flow += delta, E[u ^ 1].flow -= delta;
    maxFlow += delta;
  }

  void edmondsKarp() {
    while (findPath()) incFlow();
  }

  int getFlow(int u, int v) {
    for (int id: a[u])
    if (E[id].v == v)
     return E[id].flow;
    return 0;
  }
} G;

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
#ifdef _LAD_
  freopen("FLOW1.txt", "r", stdin);
#endif // _LAD_
  cin >> n >> nProblem;

  G.source = n + n + nProblem + nProblem + 1;
  G.sink = G.n = G.source + 1; //* number of vertexes equals sink

  string line;
  getline(cin, line);
  for (int side = 0; side <= 1; ++side) {
    for (int i = 1; i <= n; ++i) {
      getline(cin, line);
      istringstream input(line);
      int prob;
      while (input >> prob) {
        if (side == 0)
          G.addEdge(contestant(side, i), problem(0, prob), 1);
        else
          G.addEdge(problem(1, prob), contestant(side, i), 1);
      }
    }
  }

  for (int i = 1; i <= n; ++i)
    G.addEdge(G.source, contestant(0, i), 1);
  for (int i = 1; i <= n; ++i)
    G.addEdge(contestant(1, i), G.sink, 1);
  for (int i = 1; i <= nProblem; ++i)
    G.addEdge(problem(0, i), problem(1, i), 1);

  G.edmondsKarp();
  for (int i = 1; i <= nProblem; ++i) {
    if (G.getFlow(problem(0, i), problem(1, i))) {
      for (int id: G.a[problem(0, i)])
      if (G.E[id].v <= n && G.E[id].flow) {
        cout << G.E[id].v << ' ';
        break;
      }
      for (int id: G.a[problem(1, i)])
      if (n < G.E[id].v && G.E[id].v <= n + n && G.E[id].flow) {
        cout << G.E[id].v - n << endl;
        break;
      }
    } else {
      cout << 0 << ' ' << 0 << endl;
    }
  }
  return 0;
}

Code mẫu của RR

{$R+,Q+}
PROGRAM FLOW1;
CONST
  fi='';
  fo='';
  maxn=255;
  max=2;
TYPE
  stack=^ds;
  ds=record data:integer; next:stack; end;
VAR
  n,m:byte;
  c,d:array[0..maxn*4+1,0..maxn*4+1] of byte;
  xet:array[0..maxn*4+1] of boolean;
  dt:array[0..maxn*4+1] of shortint;
  pre:array[0..maxn*4+1] of integer;
  top:stack;
  timeold:longint;
Procedure ReadInput;
Var
  f:text;
  i,j:integer;
Begin
  Assign(f,fi); Reset(f);
  Readln(f,n,m);
  For i:=1 to n do
  begin
    While not Eoln(f) do
      begin
        Read(f,j);
        c[i,n+j]:=1;
      end;
    Readln(f);
  end;
  For i:=1 to n do
  begin
    While not Eoln(f) do
      begin
        Read(f,j);
        c[n+m+j,n+2*m+i]:=1;
      end;
    Readln(f);
  end;
  Close(f);
End;
Procedure Init;
Var
  i:integer;
Begin
  For i:=1 to n do c[0,i]:=1;
  For i:=1 to n do c[2*m+n+i,2*m+2*n+1]:=1;
  For i:=1 to m do c[n+i,n+m+i]:=1;
End;
Procedure WriteOutput;
Var
  f:text;
  i,j:integer;
  found:boolean;
Begin
  Assign(f,fo); Rewrite(f);
  For i:=1 to m do
    begin
      found:=false;
      For j:=1 to n do
        If d[j,n+i]=1 then
          begin Write(f,j,' '); found:=true; end;
      If not found then Writeln(f,'0 0');
      For j:=1 to n do
        If d[n+m+i,2*m+n+j]=1 then
          begin Write(f,j,' '); end;
      If found then Writeln(f);
    end;
  Close(f);
End;
Procedure Push(a:integer);
Var
  p:stack;
Begin
  New(p); p^.data:=a; p^.next:=top; top:=p;
End;
Procedure Pop(var a:integer);
Var
  p:stack;
Begin
  p:=top; a:=p^.data; top:=p^.next; Dispose(p);
End;
Procedure KhoiTri;
Var
  i:integer;
Begin
  For i:=1 to 2*m+2*n+1 do xet[i]:=false;
  For i:=1 to 2*m+2*n+1 do dt[i]:=max;
  For i:=1 to 2*m+2*n+1 do pre[i]:=0;
  xet[0]:=true;
  dt[0]:=max;
  top:=nil;
  Push(0);
End;
Function min(a,b:shortint):shortint;
Begin
  If a<b then min:=a else min:=b;
End;
Procedure GanNhan(u:integer);
Var
  i:integer;
Begin
  For i:=1 to 2*m+2*n+1 do
    If (not xet[i]) and (d[u,i]<c[u,i]) and (c[u,i]>0) then
      begin
        xet[i]:=true;
        Push(i);
        dt[i]:=min(dt[u],c[u,i]-d[u,i]);
        pre[i]:=u;
      end
  else
    If (not xet[i]) and (d[i,u]>0) and (c[i,u]>0) then
      begin
        xet[i]:=true;
        Push(i);
        dt[i]:=min(d[i,u],dt[u]);
        pre[i]:=-u;
      end;
End;
Procedure TangLuong;
Var
  x,truoc:integer;
Begin
  x:=2*m+2*n+1;
  repeat
    truoc:=pre[x];
    If truoc>=0 then d[truoc,x]:=d[truoc,x]+dt[2*m+2*n+1]
    else d[x,-truoc]:=d[x,-truoc]-dt[2*m+2*n+1];
    truoc:=abs(truoc);
    x:=truoc;
  until x=0;
End;
Procedure Solve;
Var
  u:integer;
Begin
  repeat
    KhoiTri;
    While (top<>nil) and (not xet[2*m+2*n+1]) do
      begin
        Pop(u);
        GanNhan(u);
      end;
    TangLuong;
  until not xet[2*m+2*n+1];
End;
BEGIN
  ReadInput;
  Init;
  Solve;
  WriteOutput;
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<sstream>
#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 MS(a, x) memset(a, x, sizeof(a))
#define SZ(a) (int)(a.size())
//#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;

// Dinic

void OPEN(){
    freopen("A.in","r",stdin);
    freopen("A.out","w",stdout);
}

#define maxn 1311
#define maxe (1 << 20)

struct Dinic{
    int s, t, E, adj[maxe], cap[maxe], flow[maxe], next[maxe],
    last[maxn], que[maxn], level[maxn], run[maxn];

    void init(int _s, int _t){
        s = _s; t = _t; E = 0;
        memset(last, -1, sizeof(last));
    }

    void add(int u, int v, int c1, int c2){
        adj[E] = v; cap[E] = c1; flow[E] = 0; next[E] = last[u]; last[u] = E++;
        adj[E] = u; cap[E] = c2; flow[E] = 0; next[E] = last[v]; last[v] = E++;
    }

    bool bfs(){
        memset(level, -1, sizeof(level));
        level[s] = 0;
        int size = 0; que[size++] = s;
        rep(i, size){
            for(int u = que[i], e = last[u]; e != -1; e = next[e]){
                int v = adj[e];
                if(level[v] == -1 && flow[e] < cap[e]){
                    level[v] = level[u] + 1;
                    que[size++] = v;
                }
            }
        }
        return level[t] != -1;
    }

    int dfs(int u, int bot){
        if(u == t) return bot;
        for(int &e = run[u]; e != -1; e = next[e]){
            int v = adj[e], delta;
            if(level[v] == level[u] + 1 && flow[e] < cap[e] && (delta = dfs(v, min(bot, cap[e] - flow[e]))) > 0){
                flow[e] += delta;
                flow[e ^ 1] -= delta;
                return delta;
            }
        }
        return 0;
    }

    ll maxflow(){
        ll total = 0;
        while(bfs()){
            memcpy(run, last, sizeof(last));
            for(int delta = dfs(s, oo); delta > 0; delta = dfs(s, oo)) total += delta;
        }
        return total;
    }

}dinic;

int n, m, x;
char s[11111];
vector<pair<int, int> > V1[300], V2[300];

int main(){
    //OPEN();
    scanf("%d %d\n", &n, &m);
    dinic.init(0, 2 * n + 2 * m + 1);
    FOR(i, 1, m) dinic.add(n + i, n + m + i, 1, 0);
    FOR(i, 1, n) dinic.add(0, i, 1, 0);
    FOR(i, 1, n) dinic.add(n + m + m + i, n + n + m + m + 1, 1, 0);
    FOR(i, 1, n){
        gets(s);
        istringstream iss(s);
        while(iss >> x){
            V1[x].PB(MP(dinic.E, i));
            dinic.add(i, n + x, 1, 0);
        }
    }

    FOR(i, 1, n){
        gets(s);
        istringstream iss(s);
        while(iss >> x){
            V2[x].PB(MP(dinic.E, i));
            dinic.add(n + m + x, n + m + m + i, 1, 0);
        }
    }

   // printf("%lld\n",dinic.maxflow());
    dinic.maxflow();

    FOR(i, 1, m){
        int t1 = 0, t2 = 0;
        rep(j, SZ(V1[i])) if(dinic.flow[V1[i][j].fi]) t1 = V1[i][j].se;
        rep(j, SZ(V2[i])) if(dinic.flow[V2[i][j].fi]) t2 = V2[i][j].se;
        printf("%d %d\n",t1,t2);
    }
}

Code mẫu của ll931110

{$MODE DELPHI}
program FLOW1;
const
  input  = '';
  output = '';
  maxn = 1200;
type
  PNode = ^TNode;
  TNode = record
    val: integer;
    link: PNode;
  end;
var
  n,m,s,t: integer;
  c,f: array[0..maxn,0..maxn] of integer;
  a: array[0..maxn] of PNode;
  trace,queue: array[0..maxn] of integer;

procedure add(u,v,cost: integer);
var
  P: PNode;
begin
  New(P);
  P^.val := v;
  P^.link := a[u];
  a[u] := P;
  c[u,v] := cost;

  New(P);
  P^.val := u;
  P^.link := a[v];
  a[v] := P;
end;

procedure init;
var
  fi: text;
  i,v: integer;
begin
  fillchar(c, sizeof(c), 0);
  fillchar(f, sizeof(f), 0);

  assign(fi,input);
    reset(fi);

  readln(fi, n, m);
  s := 0;
  t := 2 * (m + n) + 1;
  for i := 1 to n do
    begin
      add(s,i,1);
      add(n + 2 * m + i,t,1);
    end;

  for i := 1 to n do
    begin
      while not Eoln(fi) do
        begin
          read(fi, v);
          add(i, n + v,1);
        end;
      readln(fi);
    end;

  for i := 1 to m do add(n + i,n + m + i,1);
  for i := 1 to n do
    begin
      while not Eoln(fi) do
        begin
          read(fi, v);
          add(n + m + v,n + 2 * m + i,1);
        end;
      readln(fi);
    end;

  close(fi);
end;

function FindPath: boolean;
var
  u,v: integer;
  front,rear: integer;
  P: PNode;
begin
  fillchar(trace, sizeof(trace), 0);
  trace[0] := -1;

  front := 1;
  rear := 1;
  queue[1] := s;

  repeat
    u := queue[front];
    inc(front);

    P := a[u];
    while P <> nil do
      begin
        v := P^.val;
        if (trace[v] = 0) and (c[u,v] > f[u,v]) then
          begin
            trace[v] := u;
            if v = t then exit(true);

            inc(rear);
            queue[rear] := v;
          end;
        P := P^.link;
      end;
  until front > rear;

  FindPath := false;
end;

procedure IncFlow;
var
  u,v,delta: integer;
begin
  v := t;
  delta := high(integer);
  repeat
    u := trace[v];
    if c[u,v] - f[u,v] < delta then delta := c[u,v] - f[u,v];
    v := u;
  until v = s;

  v := t;
  repeat
    u := trace[v];
    f[u,v] := f[u,v] + delta;
    f[v,u] := f[v,u] - delta;
    v := u;
  until v = s;
end;

procedure FordFulkerson;
begin
  repeat
    if not FindPath then break;
    IncFlow;
  until false;
end;

procedure printresult;
var
  fo: text;
  i,j,u,v: integer;
begin
  assign(fo, output);
    rewrite(fo);

  for i := 1 to m do
    begin
      u := 0;
      for j := 1 to n do
        if f[j,n + i] = 1 then
          begin
            u := j;
            break;
          end;

      v := 0;
      for j := 1 to n do
        if f[n + m + i,n + 2 * m + j] = 1 then
          begin
            v := j;
            break;
          end;

      writeln(fo, u, ' ', v);
    end;

  close(fo);
end;

begin
  init;
  FordFulkerson;
  printresult;
end.

Code mẫu của skyvn97

#include<bits/stdc++.h>
#define MAX   257
#define FOR(i,a,b) for (int i=(a);i<=(b);i=i+1)
#define REP(i,n) for (int i=0;i<(n);i=i+1)
#define FORE(i,v) for (__typeof((v).begin()) i=(v).begin();i!=(v).end();i++)
#define fi   first
#define se   second
using namespace std;
const int INF=(int)1e9+7;
typedef pair<int,int> ii;
class DinicFlow {
    public:
    vector<int> dist,head,q,work;
    vector<int> capa,flow,next,point;
    int n,m;
    DinicFlow() {
        n=0;m=0;        
    }
    DinicFlow(int n,int _m) {
        this->n=n;
        this->m=0;
        dist=vector<int>(n+7);
        head=vector<int>(n+7,-1);
        q=vector<int>(n+7);     
        work=vector<int>(n+7);
        int m=2*_m;
        capa=vector<int>(m+7);
        flow=vector<int>(m+7,0);
        next=vector<int>(m+7);
        point=vector<int>(m+7);     
    }
    int addedge(int u,int v,int c1,int c2) {        
        assert(c1==1 && c2==0);
        point[m]=v;capa[m]=c1;flow[m]=0;next[m]=head[u];head[u]=m;m++;
        point[m]=u;capa[m]=c2;flow[m]=0;next[m]=head[v];head[v]=m;m++;
        return (m-2);
    }
    bool bfs(int s,int t) {
        FORE(it,dist) *it=-1;
        int sz=1;
        q[0]=s;dist[s]=0;
        REP(x,sz) {
            int u=q[x];
            for (int i=head[u];i>=0;i=next[i])
                if (dist[point[i]]<0 && flow[i]<capa[i]) {
                    dist[point[i]]=dist[u]+1;
                    q[sz]=point[i];
                    sz++;
                }
        }
        return (dist[t]>=0);
    }
    int dfs(int s,int t,int f) {
        if (s==t) return (f);
        for (int &i=work[s];i>=0;i=next[i])
            if (dist[point[i]]==dist[s]+1 && flow[i]<capa[i]) {
                int d=dfs(point[i],t,min(f,capa[i]-flow[i]));
                if (d>0) {
                    flow[i]+=d;
                    flow[i^1]-=d;
                    return (d);
                }
            }
        return (0);
    }
    int maxflow(int s,int t) {
        int ret=0;
        while (bfs(s,t)) {
            FOR(i,1,n) work[i]=head[i];
            while (true) {
                int d=dfs(s,t,INF);
                if (d<=0) break;
                ret+=d;
            }
        }
        return (ret);
    }
};
DinicFlow g;
int m,n;
vector<ii> fth[MAX],fsp[MAX];
ii res[MAX];
void init(void) {   
    cin >> n >> m;  
    int ne=2*n+m;
    string zz;
    getline(cin,zz);
    FOR(i,1,n) {
        string tmp;
        getline(cin,tmp);
        stringstream ss;
        ss << tmp;
        int t;
        while (ss >> t) {
            fth[i].push_back(ii(t,0));
            ne++;
        }
    }
    FOR(i,1,n) {
        string tmp;
        getline(cin,tmp);
        stringstream ss;
        ss << tmp;
        int t;
        while (ss >> t) {
            fsp[i].push_back(ii(t,0));
            ne++;
        }
    }   
    g=DinicFlow(2*(n+m+1),ne);      
    FOR(i,1,n) {
        FORE(it,fth[i]) it->se=g.addedge(i,n+it->fi,1,0);
        FORE(it,fsp[i]) it->se=g.addedge(n+m+it->fi,i+n+2*m,1,0);   
        g.addedge(2*(n+m)+1,i,1,0);
        g.addedge(n+2*m+i,2*(n+m+1),1,0);
    }
    FOR(i,1,m) g.addedge(n+i,n+m+i,1,0);    
}
void process(void) {
    assert(g.maxflow(2*(n+m)+1,2*(n+m+1))==n);
    FOR(i,1,m) res[i]=ii(0,0);
    FOR(i,1,n) {
        FORE(it,fth[i]) if (g.flow[it->se]>0) res[it->fi].fi=i;
        FORE(it,fsp[i]) if (g.flow[it->se]>0) res[it->fi].se=i;
    }
    FOR(i,1,m) printf("%d %d\n",res[i].fi,res[i].se);
}
int main(void) {
#ifndef ONLINE_JUDGE
    freopen("tmp.txt","r",stdin);
#endif  
    init();
    process();
}

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.