Hướng dẫn giải của Hai đường đi


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

const fi='';
      fo='';
      maxn=111;
      maxc=1000000000;
var n,s,f,res1,res2:longint;
    a:array[1..maxn,1..maxn] of longint;
    d,tr,r1,r2:array[0..maxn] of longint;
    free:array[1..maxn] of boolean;
    dau:array[1..maxn,1..maxn] of boolean;

procedure rf;
var i,x,y,t,m:longint;
begin
     assign(input,fi); reset(input);
     read(n,m,s,f);
     for x:=1 to n do
         for y:=1 to n do
             dau[x,y]:=false;
     for i:=1 to m do
     begin
          readln(x,y,t);
          if not dau[x,y] or (a[x,y]>t) then
          begin
               a[x,y]:=t; a[y,x]:=t;
               dau[x,y]:=true; dau[y,x]:=true;
          end;
     end;
     close(input);
end;

procedure dijk;
var i,j,x,min:longint;
begin
     for i:=1 to n do
     begin
          free[i]:=true;
          d[i]:=maxc;
          tr[i]:=i;
     end;
     x:=s; d[x]:=0; free[x]:=false;
     repeat
           for i:=1 to n do
               if free[i] and dau[x,i] and (d[i]>d[x]+a[x,i]) then
               begin
                    d[i]:=d[x]+a[x,i];
                    tr[i]:=x;
               end;
           j:=0; min:=maxc-1;
           for i:=1 to n do
               if free[i] and (d[i]<min) then
               begin
                    min:=d[i];
                    j:=i;
               end;
           x:=j; free[x]:=false;
     until not free[f];
     repeat
           j:=tr[x];
           dau[j,x]:=false; a[x,j]:=-a[x,j];
           x:=j;
     until x=s;
     res1:=d[f];
end;

procedure ford;
var i,x,y:longint; kt:boolean;
begin
     for i:=1 to n do
     begin
          d[i]:=maxc;
          tr[i]:=i;
     end;
     d[s]:=0;
     for i:=1 to n-1 do
     begin
          kt:=false;
          for y:=1 to n do
              for x:=1 to n do
                  if dau[y,x] and (d[x]>d[y]+a[y,x]) then
                  begin
                       d[x]:=d[y]+a[y,x];
                       tr[x]:=y;
                       kt:=true;
                  end;
          if not kt then break;
     end;
     x:=f;
     repeat
           y:=tr[x];
           dau[y,x]:=false;
           x:=y;
     until x=s;
     res2:=d[f];
end;

procedure pr;
var i,x,y:longint;
begin
     dijk;
     ford;
     for x:=1 to n-1 do
         for y:=x+1 to n do
             if dau[x,y] and dau[y,x] then
             begin
                  dau[x,y]:=false;
                  dau[y,x]:=false;
             end;
     r1[0]:=1; r2[0]:=1;
     r1[1]:=f; r2[1]:=f;
     x:=f;
     repeat
           for i:=1 to n do
               if dau[x,i] then break;
           inc(r1[0]);
           r1[r1[0]]:=i;
           dau[x,i]:=false;
           x:=i;
     until x=s;
     x:=f;
     repeat
           for i:=1 to n do
               if dau[x,i] then break;
           inc(r2[0]);
           r2[r2[0]]:=i;
           dau[x,i]:=false;
           x:=i;
     until x=s;
end;

procedure wf;
var i:longint;
begin
     assign(output,fo); rewrite(output);
     writeln(res1+res2);
     write(r1[0],' ');
     for i:=r1[0] downto 1 do write(r1[i],' ');
     writeln;
     write(r2[0],' ');
     for i:=r2[0] downto 1 do write(r2[i],' ');
     close(output);
end;

begin
     rf;
     pr;
     wf;
end.

Code mẫu của happyboy99x

#include<cstdio>
#include<climits>
#include<queue>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;

typedef pair<int, int> ii;
#define N 100
int c[N][N], d[N], t[N], n, m, s, f;

void enter() {
    scanf("%d%d%d%d",&n,&m,&s,&f);
    --s; --f;
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < n; ++j)
            c[i][j] = INT_MAX;
    for(int i = 0; i < m; ++i) {
        int u, v, l; scanf("%d%d%d",&u,&v,&l);
        --u; --v; c[u][v] = c[v][u] = l;
    }
}

int Dijkstra() {
    priority_queue<ii, vector<ii>, greater<ii> > qu;
    fill(d, d+n, INT_MAX); d[s] = 0; t[s] = -1;
    qu.push(ii(0, s));
    while(!qu.empty()) {
        int du = qu.top().first, u = qu.top().second; qu.pop();
        if(du > d[u]) continue;
        for(int v = 0; v < n; ++v)
            if(c[u][v] != INT_MAX && du + c[u][v] < d[v]) {
                qu.push(ii(d[v] = du + c[u][v], v));
                t[v] = u;
            }
    }
    for(int v = f; t[v] != -1; v = t[v]) {
        c[v][t[v]] = -c[v][t[v]];
        c[t[v]][v] = INT_MAX;
    }
    return d[f];
}

int FordBellman() {
    fill(d, d+n, INT_MAX); d[s] = 0; t[s] = -1;
    for(int step = 0, stop = 0; step < n-1 && !stop; ++step) {
        stop = 1;
        for(int u = 0; u < n; ++u) if(d[u] != INT_MAX)
            for(int v = 0; v < n; ++v) if(c[u][v] != INT_MAX && d[u] + c[u][v] < d[v]) {
                d[v] = d[u] + c[u][v];
                t[v] = u;
                stop = 0;
            }
    }
    for(int v = f; t[v] != -1; v = t[v]) c[t[v]][v] = INT_MAX; 
    return d[f];
}

void EditGraph() {
    for(int i = 0; i < n; ++i)
        for(int j = i + 1; j < n; ++j)
            if(c[i][j] != INT_MAX && c[j][i] != INT_MAX)
                c[i][j] = c[j][i] = INT_MAX;
}

stack<int> st;
void dfs(int u) {
    if(u == s) {
        printf("%d %d", st.size() + 1, s+1);
        for(; !st.empty(); st.pop()) printf(" %d", st.top()+1);
        printf("\n");
    } else
        for(int v = 0; v < n; ++v)
            if(c[u][v] != INT_MAX) {
                st.push(u);
                dfs(v);
            }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    enter();
    printf("%d\n", Dijkstra() + FordBellman());
    EditGraph();
    dfs(f);
    return 0;
}

Code mẫu của ladpro98

#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <ctime>
#include <memory.h>
#include <cassert>

#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define REP(i, a, b) for(int i = (a); i <=(b); ++i)
#define FORD(i, a, b) for(int i = (a); i > (b); --i)
#define REPD(i, a, b) for(int i = (a); i >=(b); --i)
#define TR(it, a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#define RESET(a, v) memset(a, (v), sizeof(a))
#define SZ(a) (int(a.size()))
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define LL long long
#define LD long double
#define II pair<int, int>
#define X first
#define Y second
#define VI vector<int>
#define VII vector<II>
#define endl '\n'

const int N = 111;
const int INF = INT_MAX;

using namespace std;

int T[N], d[N];
bool inQ[N], was[N];
int cost[N][N], cap[N][N], flow[N][N];
int n, m, source, sink, minCost, maxFlow;

bool findPath() {
  queue<int> Q;
  REP(i, 1, n) {
    T[i] = 0; d[i] = INF; inQ[i] = 0;
  }
  Q.push(source); d[source] = 0; inQ[source] = 1;
  while (!Q.empty()) {
    int u = Q.front(); Q.pop(); inQ[u] = 0;
    REP(v, 1, n)
    if (flow[u][v] < cap[u][v]) {
      int uv = cost[u][v] * (flow[u][v] < 0 ? -1 : 1);
      if (d[v] > d[u] + uv) {
        T[v] = u;
        d[v] = d[u] + uv;
        if (!inQ[v]) {
          inQ[v] = 1;
          Q.push(v);
        }
      }
    }
  }
  return d[sink] < INF;
}

void incFlow() {
  int delta = INF;
  for (int v = sink; v != source; v = T[v])
    delta = min(delta, flow[T[v]][v] < 0 ? -flow[T[v]][v] : (cap[T[v]][v] - flow[T[v]][v]));
  for (int v = sink; v != source; v = T[v])
    flow[T[v]][v] += delta, flow[v][T[v]] -= delta;
  maxFlow += delta;
  minCost += delta * d[sink];
}

VI path;

void showPath(int u) {
  path.PB(u);
  was[u] = 1;
  REP(v, 1, n)
  if (flow[u][v] > 0 && !was[v]) {
    showPath(v); break;
  }
}

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  #ifdef _LAD_
    freopen("HIWAY.in", "r", stdin);
  #endif // _LAD_
  cin >> n >> m >> source >> sink;
  int u, v;
  FOR(i, 0, m) {
    cin >> u >> v; cin >> cost[u][v];
    cost[v][u] = cost[u][v];
    cap[u][v] = cap[v][u] = 1;
  }
  ++n;
  cap[n][source] = 2;
  int S = source; source = n;
  while (findPath()) incFlow();
  if (maxFlow < 2) cout << -1 << endl;
  else {
    cout << minCost << endl;
    showPath(S);
    cout << SZ(path) << ' ';
    for (int it: path) cout << it << ' '; cout << endl;
    was[sink] = 0; path.clear();
    showPath(S);
    cout << SZ(path) << ' ';
    for (int it: path) cout << it << ' '; cout << endl;
  }
  return 0;
}

Code mẫu của RR

var
  cnt,res,k,u,v,n,m,s,t,ss:longint;
  fl,a,c,trace:array[1..111,1..111] of longint;
  kq:array[1..111] of longint;

procedure print(s:longint);
    var
      u:longint;
    begin
      inc(cnt); kq[cnt]:=s;
      if s=t then exit;
      for u:=1 to n do
        if fl[s,u]=1 then
          begin
            fl[s,u]:=0;
            print(u);
            exit;
          end;
    end;

begin
  read(n,m,s,t);

  for u:=1 to n do
  for v:=1 to n do
    begin
      a[u,v]:=1000111000;
      if u=v then a[u,v]:=0;
      trace[u,v]:=v;
    end;

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

  c:=a;
  for k:=1 to n do
    for u:=1 to n do
    for v:=1 to n do
      if c[u,v]>c[u,k]+c[k,v] then
        begin
          c[u,v]:=c[u,k]+c[k,v];
          trace[u,v]:=trace[u,k];
        end;
  res:=c[s,t];

  ss:=s;
  while ss<>t do
    begin
      fl[ss,trace[ss,t]]:=1;
      a [trace[ss,t],ss]:=-a[ss,trace[ss,t]];
      a [ss,trace[ss,t]]:=1000111000;
      ss:=trace[ss,t];
    end;

  c:=a;
  for u:=1 to n do
  for v:=1 to n do
    trace[u,v]:=v;

  for k:=1 to n do
    for u:=1 to n do
    for v:=1 to n do
      if c[u,v]>c[u,k]+c[k,v] then
        begin
          c[u,v]:=c[u,k]+c[k,v];
          trace[u,v]:=trace[u,k];
        end;
  res:=res+c[s,t];

  ss:=s;
  while ss<>t do
    begin
      if c[ss,trace[ss,t]]<0 then fl[trace[ss,t],ss]:=0
      else fl[ss,trace[ss,t]]:=1;
      ss:=trace[ss,t];
    end;

  writeln(res);
  print(s);
  write(cnt); for u:=1 to cnt do write(' ',kq[u]); writeln;
  cnt:=0;
  print(s);
  write(cnt); for u:=1 to cnt do write(' ',kq[u]); writeln;
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;
void minimize(int &x,const int &y) {
    if (x>y) x=y;
}
class MaxFlowMinCost {
    public:
    struct edge {
        int from,to,capa,flow,cost;
        edge() {
            from=0;to=0;capa=0;flow=0;cost=0;
        }
        edge(int u,int v,int ca,int co) {
            from=u;to=v;capa=ca;flow=0;cost=co;
        }
        int residual(void) const {
            return (capa-flow);
        }       
    };
    vector<vector<int> > g;
    vector<edge> e;
    vector<int> d,tr;
    int n;  
    MaxFlowMinCost() {
        n=0;
    }
    MaxFlowMinCost(int n) {
        this->n=n;
        g.assign(n+7,vector<int>());
        e.clear();
        d=vector<int>(n+7);
        tr=vector<int>(n+7);
    }
    void addedge(int u,int v,int ca,int co) {
        g[u].push_back(e.size());
        e.push_back(edge(u,v,ca,co));
        g[v].push_back(e.size());
        e.push_back(edge(v,u,0,-co));
    }
    bool FordBellman(int s,int t) {
        FOR(i,1,n) {
            d[i]=INF;
            tr[i]=-1;
        }
        vector<bool> inq=vector<bool>(n+7,false);
        queue<int> q;
        while (!q.empty()) q.pop();
        q.push(s);d[s]=0;inq[s]=true;
        while (!q.empty()) {
            int u=q.front();q.pop();inq[u]=false;
            FORE(it,g[u]) if (e[*it].residual()>0) {
                int v=e[*it].to;
                if (d[v]>d[u]+e[*it].cost) {
                    d[v]=d[u]+e[*it].cost;
                    tr[v]=*it;
                    if (!inq[v]) {
                        q.push(v);
                        inq[v]=true;
                    }
                }
            }
        }
        return (d[t]<INF);
    }
    ii getflow(int s,int t) {
        int totflow=0;
        int totcost=0;
        while (FordBellman(s,t)) {
            int delta=INF;
            for (int u=t;u!=s;u=e[tr[u]].from) minimize(delta,e[tr[u]].residual());
            for (int u=t;u!=s;u=e[tr[u]].from) {
                e[tr[u]].flow+=delta;
                e[tr[u]^1].flow-=delta;
            }
            totflow+=delta;
            totcost+=delta*d[t];
        }
        return (ii(totflow,totcost));
    }
};
MaxFlowMinCost g;
int n,m,s,t;
queue<int> q[MAX];
void loadgraph(void) {
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&s);
    scanf("%d",&t);
    g=MaxFlowMinCost(n+1);
    REP(i,m) {
        int u,v,c;
        scanf("%d",&u);
        scanf("%d",&v);
        scanf("%d",&c);
        g.addedge(u,v,1,c);
        g.addedge(v,u,1,c);
    }
    g.addedge(n+1,s,2,0);
}
void process(void) {
    ii res=g.getflow(n+1,t);
    if (res.fi<2) {
        printf("-1");
        return;
    }
    printf("%d\n",res.se);
    FORE(it,g.e) if (it->flow>0 && it->from<=n) q[it->from].push(it->to);
    REP(i,2) {
        vector<int> way;
        way.clear();
        int u=s;
        while (u!=t) {
            assert(!q[u].empty());
            way.push_back(u);
            int v=q[u].front();q[u].pop();
            u=v;
        }
        way.push_back(t);
        printf("%d",way.size());
        FORE(it,way) printf(" %d",*it);
        printf("\n");
    }
}
int main(void) {
    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.