Hướng dẫn giải của Total Flow


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 ladpro98

#include <bits/stdc++.h>
const int n = 57;
const int t = 25;
const int oo = trunc(1e9);
using namespace std;
bool Link[n][n];
int c[n][n], f[n][n];
int Q[n], T[n];
int m;

bool FindPath() {
    int l = 1, r = 1, i, u;
    Q[1] = 0;
    for(i=0; i<n; i++) T[i] = 0;
    while (l <= r) {
        u = Q[l++];
        for(i=0; i<n; i++)
        if (Link[u][i] && T[i]==0 && c[u][i]>f[u][i]){
            Q[++r] = i;
            T[i] = u;
            if (i == t) return true;
        }
    }
    return false;
}

void IncFlow() {
    int v = t, delta = oo, u;
    while (v) {
        u = T[v];
        delta = min(delta, c[u][v] - f[u][v]);
        v = u;
    }
    v = t;
    while (v) {
        u = T[v];
        f[u][v] += delta;
        f[v][u] -= delta;
        v = u;
    }
}

int main()
{
    scanf("%d\n", &m);
    int w, u, v; char x, y;
    while (m--) {
        scanf("%c %c %d\n", &x, &y, &w);
        if ('a' <= x && x <= 'z')
            u = x - 'a' + 'Z' - 'A' + 1; else u = x - 'A';
        if ('a' <= y && y <= 'z')
            v = y - 'a' + 'Z' - 'A' + 1; else v = y - 'A';
        c[u][v] += w;
        Link[u][v] = true;
    }
    while (FindPath()) IncFlow();
    int res = 0;
    for(int i=0; i<n; i++)
        if (Link[0][i]) res += f[0][i];
    printf("%d", res);
    return 0;
}

Code mẫu của RR

{$R+,Q+}
uses math;
const
  FINP='';
  FOUT='';
  oo=1000000001;
var
  f1,f2:text;
  fl,now:array['A'..'z','A'..'z'] of longint;
  tr:array['A'..'z'] of char;
  queue:array[1..100] of char;
  first,last,sum:longint;
procedure openF;
begin
  assign(f1,FINP); reset(f1);
  assign(f2,FOUT); rewrite(f2);
end;
procedure closeF;
begin
  close(f1);
  close(f2);
end;
procedure inp;
var
  c1,c2:char;
  m,c:longint;
begin
  readln(f1,m);
  for m:=1 to m do
    begin
      read(f1,c1,c2,c2);
      readln(f1,c);
      fl[c1,c2]+=c;
    end;
end;
procedure findPath;
var
  u,v:char;
begin
  fillchar(tr,sizeof(tr),'0');
  first:=1; last:=1; queue[1]:='A';
  while first<=last do
    begin
      u:=queue[first]; inc(first);
      if u='Z' then exit;
      for v:='A' to 'z' do
      if (fl[u,v]>now[u,v]) and (tr[v]='0') then
        begin
          tr[v]:=u;
          inc(last); queue[last]:=v;
        end;
    end;
end;
procedure enlarge;
var
  u,v:char;
  delta:longint;
begin
  v:='Z'; delta:=oo;
  repeat
    u:=tr[v];
    delta:=min(delta,fl[u,v]-now[u,v]);
    v:=u;
  until v='A';
  v:='Z'; sum+=delta;
  repeat
    u:=tr[v];
    now[u,v]+=delta;
    now[v,u]-=delta;
    v:=u;
  until v='A';
end;
procedure solve;
begin
  repeat
    findPath;
    if tr['Z']<>'0' then enlarge;
  until tr['Z']='0';
  writeln(f2,sum);
end;
begin
  openF;
  inp;
  solve;
  closeF;
end.

Code mẫu của hieult

#include <stdio.h>
//#include <conio.h>

int N, af[52][52];
int Min(int x,int y)
{
    if(x<y) return x;
    else return y;
}

int main()
{
//freopen("MTOTALF.in","r",stdin);
int i,j,dau,giua,cuoi,dinh,d;
char a,b,c;
char s[10];
scanf("%d",&N);
for(int i=0;i<=N;i++)
{
    scanf("%*c%c%*c%c%d",&a,&b,&d);
    if(a>='a'&&a<='z') a+='Z'+1-'a';
    if(b>='a'&&b<='z') b+='Z'+1-'a';
    af[a-'A'][b-'A']+=d;
    af[b-'A'][a-'A']+=d;
}
    int rutgon;
    do
    {
        rutgon=0;
        for(giua=0;giua<52;giua++)
        if(giua!=0&&giua!=25)
        {
                dau=-1;
                cuoi=-1;
                dinh=0;
                for(j=0;j<52;j++)
                if(af[giua][j]!=0)
                {
                    if(dau==-1) dau=j;
                    else if(cuoi==-1) cuoi=j;
                    else dinh=1; 
                } 
                if(dinh) continue; 
                if(cuoi!=-1)
                {
                    af[dau][cuoi]+=Min(af[dau][giua],af[giua][cuoi]);
                    af[cuoi][dau]+=Min(af[dau][giua],af[giua][cuoi]); 
                    af[dau][giua]=0;
                    af[giua][dau]=0;
                    af[cuoi][giua]=0;
                    af[giua][cuoi]=0;
                    rutgon=1; 
                } 
                else if(dau!=-1)
                {
                     af[dau][giua]=0;
                     af[giua][dau]=0;
                     rutgon=1; 
                } 
        }
    }
    while(rutgon);
printf("%ld",af[0][25]);
//getch();
}

Code mẫu của ll931110

{$MODE DELPHI}
program MTOTALF;
const
  input  = '';
  output = '';
  maxn = 52;
  maxv = 3000;
var
  lab: array['A'..'z'] of integer;
  c,f: array[1..maxn,1..maxn] of integer;
  queue,trace: array[1..maxn] of integer;
  front,rear: integer;
  s,t: integer;
  n: integer;

procedure init;
var
  fi: text;
  i,a1,a2,cost: integer;
  chx,chy: char;
begin
  for chx := 'A' to 'Z' do lab[chx] := ord(chx) - ord('A') + 1;
  for chx := 'a' to 'z' do lab[chx] := ord(chx) - ord('a') + 27;
  s := 1;  t := 26;

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

  fillchar(c, sizeof(c), 0);

  readln(fi, n);
  for i := 1 to n do
    begin
      read(fi, chx);
      read(fi, chy);
      read(fi, chy);
      readln(fi, cost);

      a1 := lab[chx];
      a2 := lab[chy];
      c[a1,a2] := c[a1,a2] + cost;
      c[a2,a1] := c[a2,a1] + cost;
    end;

  close(fi);
end;

function findpath: boolean;
var
  front,rear: integer;
  u,v: integer;
begin
  for u := 1 to maxn do trace[u] := maxv;
  trace[s] := -1;

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

    for v := 1 to maxn do
      if (trace[v] = maxv) and (c[u,v] > f[u,v]) then
        begin
          trace[v] := u;
          if v = t then exit(true);

          inc(rear);
          queue[rear] := v;
        end;
  until front > rear;

  findpath := false;
end;

procedure incflow;
var
  delta,u,v: 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 maxflow;
begin
  fillchar(f, sizeof(f), 0);
  repeat
    if not findpath then break;
    incflow;
  until false;
end;

procedure printresult;
var
  i,res: integer;
  fo: text;
begin
  res := 0;
  for i := 1 to maxn do if f[s,i] > 0 then res := res + f[s,i];

  assign(fo, output);
    rewrite(fo);
    writeln(fo, res);
  close(fo);
end;

begin
  init;
  maxflow;
  printresult;
end.

Code mẫu của khuc_tuan

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {

    static class Node {
        int id;
        ArrayList<Edge> ke;

        Node() {
            ke = new ArrayList<Edge>();
        }

        Node(int id) {
            this.id = id;
            ke = new ArrayList<Edge>();
        }
    }

    static class Edge {
        Node a, b;
        int cap, flow;

        Edge(Node a, Node b, int cap) {
            this.a = a;
            this.b = b;
            this.cap = cap;
            this.flow = 0;
            a.ke.add(this);
        }
    }

    static Node[] nodes;
    static boolean[] vs;

    static boolean dfs(Node n) {
        if (vs[n.id])
            return false;
        vs[n.id] = true;
        if (n.id == 'Z')
            return true;
        for (Edge e : n.ke)
            if (e.flow < e.cap && dfs(e.b)) {
                ++e.flow;
                return true;
            }
        return false;
    }

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        nodes = new Node[300];
        for (int i = 0; i < nodes.length; ++i)
            nodes[i] = new Node(i);
        int m = sc.nextInt();
        for (int i = 0; i < m; ++i) {
            char a = sc.next().charAt(0);
            char b = sc.next().charAt(0);
            int c = sc.nextInt();
            new Edge(nodes[a], nodes[b], c);
            new Edge(nodes[b], nodes[a], c);
        }
        vs = new boolean[300];
        int res = 0;
        while (true) {
            Arrays.fill(vs, false);
            if (!dfs(nodes['A']))
                break;
            ++res;
        }
        System.out.println(res);
    }
}

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.