Hướng dẫn giải của Mạng truyền tin


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>
#define ii pair<int, int>
#define iii pair<int, ii>
#define X first
#define Y second

const int N = 111;
const int oo = trunc(1e9);
const int V = N * N;
using namespace std;
vector<iii> e;
vector<int> a[N];
int c[N][N], f[N][N], T[N], Q[N];
int m, n, s, t, res, ans;

void Enter() {
    //freopen("NKNET.in", "r", stdin);
    scanf("%d %d\n", &n, &m);
    int u, v, c;
    for(int i=1; i<=m; i++) {
        scanf("%d %d %d\n", &u, &v, &c);
        e.push_back(iii(c, ii(u, v)));
        a[u].push_back(v);
        a[v].push_back(u);
    }
    scanf("%d %d", &s, &t);
}

void Init(int lim) {
    //initialize network
    int i, j, u, v;
    for(i=1; i<=n; i++) {
        a[i].clear();
        for(j=1; j<=n; j++) {
            f[i][j] = 0;
            c[i][j] = V;
        }
    }
    for(i=0; i<m; i++)
    if (e[i].X > lim) {
        u = e[i].Y.X;
        v = e[i].Y.Y;
        a[u].push_back(v);
        a[v].push_back(u);
    }
}

void Init2(int lim) {
    int i, j, u, v;
    for(i=1; i<=n; i++) {
        a[i].clear();
        for(j=1; j<=n; j++) {
            f[i][j] = 0;
            c[i][j] = V;
        }
    }
    for(i=0; i<m; i++) {
        u = e[i].Y.X;
        v = e[i].Y.Y;
        a[u].push_back(v);
        a[v].push_back(u);

        if (e[i].X <= lim)
            c[u][v] = c[v][u] = 1;
    }
}

bool FindPath() {
    int l=1, r=1, u, v, i;
    Q[1] = s;
    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 && c[u][v] > f[u][v]) {
                Q[++r] = v;
                T[v] = u;
                if (v == t) return true;
            }
        }
    }
    return false;
}

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

int maxFlow() {
    while (FindPath()) IncFlow();
    int flow = 0;
    for(int i=0; i<a[s].size(); i++)
        flow += f[s][a[s][i]];
    return flow;
}

int main()
{
    Enter();
    //BinarySearch the answer
    int l = 0, r = V, mid;
    while (l <= r) {
        mid = (l + r) / 2;
        Init(mid);
        if (FindPath()) {
            l = mid + 1;
        }
        else {
            res = mid;
            r = mid - 1;
        }
    }
    Init2(res);
    ans = maxFlow();
    printf("%d\n", ans);
    for(int i=1; i<=n; i++)
    if (i == s || T[i] > 0) {
        for(int j=0; j<a[i].size(); j++) {
            int v = a[i][j];
            if (T[v] == 0) printf("%d %d\n", i, v);
        }
    }
    return 0;
}

Code mẫu của RR

//Wishing myself a happy lunar new year with a lot of accept solutions
//Written by Nguyen Thanh Trung
uses math;
const
  finp='';
  fout='';
  maxn=101;
  oo=1000000;
var
  s,t,m,n:longint;
  queue,trace:array[0..maxn] of longint;
  c,c2,f:array[0..maxn,0..maxn] of longint;
procedure readinp;
var
  i,u,v:longint;
begin
  assign(input,finp);  reset(input);
  read(n,m);
  for i:=1 to m do
  begin
    read(u,v,c[u,v]);
    c[v,u]:=c[u,v];
  end;
  read(s,t);
  close(input);
end;
function findpath:boolean;
var
  first,last,i,j:longint;
begin
  fillchar(trace,sizeof(trace),0);
  first:=0;
  last:=1;
  queue[1]:=s;
  trace[s]:=n+1;
  while first<last do
  begin
    inc(first);
    i:=queue[first];
    for j:=1 to n do
    if (trace[j]=0) and (f[i,j]<c[i,j]) then
      begin
        trace[j]:=i;
        inc(last);
        queue[last]:=j;
        if j=t then exit(true);
      end;
  end;
  exit(false);
end;
procedure incflow;
var
  i,j,delta:longint;
begin
  delta:=oo;
  j:=t;
  repeat
    i:=trace[j];
    if delta>c[i,j]-f[i,j] then delta:=c[i,j]-f[i,j];
    j:=i;
  until j=s;
  j:=t;
  repeat
    i:=trace[j];
    inc(f[i,j],delta);
    dec(f[j,i],delta);
    j:=i;
  until j=s;
end;
function check(val:longint):boolean;
var
  i,j,cost:longint;
  ok:boolean;
begin
  c2:=c;
  for i:=1 to n do
  for j:=1 to n do
    if (c[i,j]<>0) and (c[i,j]<=val) then c[i,j]:=1
    else if c[i,j]>val then c[i,j]:=oo;
  fillchar(f,sizeof(f),0);
  ok:=false;
  repeat
    if not findpath then break;
    incflow;
  until ok;
  cost:=0;
  for i:=1 to n do
    if f[s,i]>0 then inc(cost,f[s,i]);
  c:=c2;
  if cost>=oo then exit(false) else exit(true);
end;
procedure printresult(val:longint);
var
  i,j,cost:longint;
  ok:boolean;
  fo:text;
begin
  for i:=1 to n do
  for j:=1 to n do
    if (c[i,j]<>0) and (c[i,j]<=val) then c[i,j]:=1
    else if (c[i,j]<>0) then c[i,j]:=oo;
  fillchar(f,sizeof(f),0);
  ok:=false;
  repeat
    if not findpath then break;
    incflow;
  until ok;
  cost:=0;
  for i:=1 to n do
    if f[s,i]>0 then inc(cost,f[s,i]);
  assign(fo,fout); rewrite(fo);
  writeln(fo,cost);
  for i:=1 to n do
  for j:=1 to n do
    if (c[i,j]<>0) and (trace[i]<>0) and (trace[j]=0)
    then writeln(fo,i,' ',j);
  close(fo);
end;
procedure solve;
var
  left,right,mid:longint;
begin
  left:=0;  right:=101;
  repeat
    mid:=(left+right) div 2;
    if check(mid) then right:=mid else left:=mid;
  until left=right-1;
  if check(left) then printresult(left) else printresult(right);
end;
begin
  readinp;
  solve;
end.

Code mẫu của ll931110

program NKNET;
const
  input  = '';
  output = '';
  maxn = 100;
  maxm = 10000;
  maxv = 1000000;
var
  a,c,f: array[1..maxn,1..maxn] of longint;
  n,m: longint;

  queue,trace: array[1..maxn] of longint;
  front,rear: longint;

  s,t: longint;
  time: longint;

  cc: longint;
  lx,ly,t1,t2: array[1..maxm] of longint;
  l1,l2: longint;

procedure init;
var
  fi: text;
  i,j,u,v: longint;
begin
  assign(fi, input);
    reset(fi);

  read(fi, n, m);
  fillchar(a, sizeof(a), 0);

  for i := 1 to m do
    begin
      readln(fi, u, v, a[u,v]);
      a[v,u] := a[u,v];
    end;

  readln(fi, s, t);

  close(fi);
end;

function ok(x: longint): boolean;
var
  u,v: longint;
begin
  fillchar(trace, sizeof(trace), 0);
  front := 1;  rear := 1;  queue[1] := s;
  trace[s] := -1;

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

    for v := 1 to n do
      if (trace[v] = 0) and (a[u,v] > x) then
        begin
          trace[v] := u;
          if v = t then exit(false);

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

  ok := true;
end;

procedure settime;
var
  inf,sup,med: longint;
begin
  inf := 0;
  sup := maxn;

  repeat
    med := (inf + sup) div 2;
    if ok(med) then
      begin
        time := med;
        sup := med - 1;
      end
    else inf := med + 1;
  until inf > sup;
end;

function FindPath: boolean;
var
  u,v: longint;
begin
  fillchar(trace, sizeof(trace), 0);
  front := 1;  rear := 1;  queue[1] := s;
  trace[s] := -1;

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

    for v := 1 to n do
      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;
  until front > rear;

  FindPath := false;
end;

procedure IncFlow;
var
  d,u,v: longint;
begin
  d := high(longint);
  v := t;

  repeat
    u := trace[v];
    if c[u,v] - f[u,v] < d then d := c[u,v] - f[u,v];
    v := u;
  until v = s;

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

procedure FordFulkerson;
var
  i,j,u,v: longint;
begin
  fillchar(c, sizeof(c), 0);
  for i := 1 to n do
    for j := 1 to n do if a[i,j] > 0 then
        begin
          if a[i,j] <= time then c[i,j] := 1 else c[i,j] := maxv;
        end;

  fillchar(f, sizeof(f), 0);
  repeat
    if not FindPath then break;
    IncFlow;
  until false;

  cc := 0;
  l1 := 0;  l2 := 0;
  for i := 1 to n do
    if trace[i] = 0 then
      begin
        inc(l2);  t2[l2] := i;
      end
    else
      begin
        inc(l1);  t1[l1] := i;
      end;

  for i := 1 to l1 do
    for j := 1 to l2 do
      begin
        u := t1[i];  v := t2[j];
        if (c[u,v] = 1) and (f[u,v] = 1) then
          begin
            inc(cc);
            lx[cc] := u;  ly[cc] := v;
          end;
      end;
end;

procedure printresult;
var
  fo: text;
  i: longint;
begin
  assign(fo, output);
    rewrite(fo);

  writeln(fo, cc);
  for i := 1 to cc do writeln(fo, lx[i], ' ', ly[i]);

  close(fo);
end;

begin
  init;
  settime;
  FordFulkerson;
  printresult;
end.

Code mẫu của skyvn97

#include<bits/stdc++.h>
#define MAX   111
#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 {
    private:    
    vector<int> dist,head,q,work;
    vector<int> capa,flow,next,point;
    int n,m;
    public:
    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);
    }
    void addedge(int u,int v,int c1,int c2) {
        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++;      
    }
    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,vector<int> &v) {
        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;
            }
        }
        v.clear();
        FOR(i,1,n) if (dist[i]>=0) v.push_back(i);
        //printf("MaxFlow %d\n",ret);
        return (ret);
    }
};
vector<ii> g[MAX];
int d[MAX];
bool src[MAX];
int n,m,s,t;
void loadgraph(void) {
    scanf("%d",&n);
    scanf("%d",&m);
    REP(i,m) {
        int u,v,c;
        scanf("%d",&u);
        scanf("%d",&v);
        scanf("%d",&c);
        g[u].push_back(ii(v,c));
        g[v].push_back(ii(u,c));
    }   
    scanf("%d",&s);
    scanf("%d",&t);
}
bool bfs(int s,int t,int x) {
    queue<int> q;
    while (!q.empty()) q.pop();
    memset(d,-1,sizeof d);
    q.push(s);
    d[s]=0;
    while (!q.empty()) {
        int u=q.front();q.pop();
        if (u==t) return (true);
        FORE(it,g[u]) if (it->se>x) {
            int v=it->fi;
            if (d[v]<0) {
                d[v]=d[u]+1;
                q.push(v);
            }
        }
    }
    return (false);
}
int findtime(void) {
    int l=0;
    int r=INF;
    while (true) {
        if (l==r) return (r);
        if (r-l==1) {
            if (!bfs(s,t,l)) return (l);
            else return (r);
        }
        int m=(l+r)>>1;
        if (!bfs(s,t,m)) r=m;
        else l=m+1;
    }
}
void process(void) {
    int ans=findtime(); 
    DinicFlow G=DinicFlow(n,m);
    FOR(i,1,n) FORE(it,g[i]) {
        int j=it->fi;
        int cst;
        if (it->se<=ans) cst=1; else cst=INF;
        if (i<j) G.addedge(i,j,cst,cst);
    }
    vector<int> v;  
    vector<ii> res;
    assert(G.maxflow(s,t,v)<INF);   
    FORE(it,v) src[*it]=true;
    FORE(it,v) FORE(jt,g[*it]) if (!src[jt->fi]) res.push_back(ii(*it,jt->fi));
    printf("%d\n",res.size());
    FORE(it,res) printf("%d %d\n",it->fi,it->se);
}
int main(void) {
#ifndef ONLINE_JUDGE
    freopen("tmp.txt","r",stdin);
    printf("START\n");
#endif
    loadgraph();
    process();
    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.