Hướng dẫn giải của Luồng với chi phí nhỏ nhất


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>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const long long oo = 1LL << 60;

struct edge
{
    long long x, y, cap, flow, cost;
};

struct MinCostMaxFlow
{
    long long n, S, T;
    vector < vector <long long> > a;
    vector <long long> dist, prev, done, pot;
    vector <edge> e;

    MinCostMaxFlow() {}
    MinCostMaxFlow(long long _n, long long _S, long long _T)
    {
        n = _n; S = _S; T = _T;
        a = vector < vector <long long> >(n + 1);
        dist = vector <long long>(n + 1);
        prev = vector <long long>(n + 1);
        done = vector <long long>(n + 1);
        pot = vector <long long>(n + 1, 0);
    }

    void addEdge(long long x, long long y, long long _cap, long long _cost)
    {
        edge e1 = {x, y, _cap, 0, _cost};
        edge e2 = {y, x, 0, 0, -_cost};
        a[x].push_back(e.size()); e.push_back(e1);
        a[y].push_back(e.size()); e.push_back(e2);
    }

    pair <long long,long long> dijkstra()
    {
        long long flow = 0, cost = 0;
        for (long long i = 1; i <= n; i++) done[i] = 0, dist[i] = oo;
        priority_queue < pair<long long,long long> > q;
        dist[S] = 0; prev[S] = -1;
        q.push(make_pair(0, S));
        while (!q.empty())
        {
            long long x = q.top().second; q.pop();
            if (done[x]) continue;
            done[x] = 1;
            for (int i = 0; i < int(a[x].size()); i++)
            {
                long long id = a[x][i], y = e[id].y;
                if (e[id].flow < e[id].cap)
                {
                    long long D = dist[x] + e[id].cost + pot[x] - pot[y];
                    if (!done[y] && D < dist[y])
                    {
                        dist[y] = D; prev[y] = id;
                        q.push(make_pair(-dist[y], y));
                    }
                }
            }
        }

        for (long long i = 1; i <= n; i++) pot[i] += dist[i];

        if (done[T])
        {
            flow = oo;
            for (long long id = prev[T]; id >= 0; id = prev[e[id].x]) 
                flow = min(flow, e[id].cap - e[id].flow);
            for (long long id = prev[T]; id >= 0; id = prev[e[id].x]) 
            {
                cost += e[id].cost * flow;
                e[id].flow += flow;
                e[id ^ 1].flow -= flow;
            }
        }

        return make_pair(flow, cost);
    }

    pair <long long,long long> minCostMaxFlow()
    {
        long long totalFlow = 0, totalCost = 0;
        while (1)
        {
            pair <long long,long long> u = dijkstra();
            if (!done[T]) break;
            totalFlow += u.first; totalCost += u.second;
        }
        return make_pair(totalFlow, totalCost);
    }
};

long long flow[111][111], hasEdge[111][111], c[111][111], cc[111][111];

int main()
{
    //freopen("i.in", "r", stdin);
    long long n, m, S, T, F, x, y, cap, cost;
    cin >> n >> m >> F >> S >> T;
    MinCostMaxFlow u(n + 2, n + 1, n + 2);
    u.addEdge(n + 1, S, F, 0);
    u.addEdge(T, n + 2, F, 0);
    while (m--)
    {
        cin >> x >> y >> cost >> cap;
        hasEdge[x][y] = hasEdge[y][x] = 1;
        c[x][y] = c[y][x] = cost;
        cc[x][y] = cc[y][x] = cap;
    }

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            if (cc[i][j] > 0)
                u.addEdge(i, j, cc[i][j], c[i][j]);

    pair <long long,long long> ans = u.minCostMaxFlow();
    if (ans.first < F) puts("-1");
    else
    {
        cout << ans.second << endl;
        for (int i = 0; i < int(u.e.size()); i++)
        {
            long long x = u.e[i].x, y = u.e[i].y;
            if (x > y) continue;
            flow[x][y] += u.e[i].flow;
        }

        for (long long i = 1; i <= n; i++)
            for (long long j = i + 1; j <= n; j++)
                if (hasEdge[i][j])
                {
                    if (flow[i][j] > 0) cout << i << ' ' << j << ' ' << flow[i][j] << endl;
                    if (flow[i][j] < 0) cout << j << ' ' << i << ' ' << -flow[i][j] << endl;
                }
        puts("0 0 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 = 222;
const int INF = INT_MAX;

using namespace std;

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

bool findPath() {
  queue<int> Q;
  REP(i, 1, n) {
    d[i] = INF;
    T[i] = 0;
    inQ[i] = 0;
  }
  Q.push(source); inQ[source] = 1; d[source] = 0LL;
  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 = (flow[u][v] < 0 ? -1 : 1) * cost[u][v];
      if (d[v] > d[u] + uv) {
        d[v] = d[u] + uv;
        T[v] = u;
        if (!inQ[v]) {
          inQ[v] = 1;
          Q.push(v);
        }
      }
    }
  }
  return T[sink] != 0;
}

void incFlow() {
  int delta = INF;
  for (int v = sink; v != source; v = T[v])
    delta = min(delta, flow[T[v]][v] >= 0 ? (cap[T[v]][v] - flow[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 += d[sink] * delta;
}

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

Code mẫu của RR

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <complex>
#include <iostream>
#include <algorithm>

#include <ctime>
#include <deque>
#include <bitset>
#include <cctype>
#include <utility>
#include <cassert>

#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--)
#define REP(i,a) for(int i=0,_a=(a); i<_a; i++)
#define EACH(it,a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)

#define DEBUG(x) { cout << #x << " = "; cout << (x) << endl; }
#define PR(a,n) { cout << #a << " = "; FOR(_,1,n) cout << a[_] << ' '; cout << endl; }
#define PR0(a,n) { cout << #a << " = "; REP(_,n) cout << a[_] << ' '; cout << endl; }

#define sqr(x) ((x) * (x))
using namespace std;


#define prev prev_

const long long F_INF = 1000111000111000LL;
const long long C_INF = 1000111000111000LL;

template<class Flow = long long, class Cost = long long>
struct MinCostFlow {
    int V, E;
    vector<Flow> cap;
    vector<Cost> cost;
    vector<int> to, prev;

    vector<Cost> dist, pot;
    vector<int> last, path, used;
    priority_queue< pair<Cost, int> > q;

    MinCostFlow(int V, int E) : V(V), E(0), cap(E*2,0), cost(E*2,0), to(E*2,0), prev(E*2,0),
            dist(V,0), pot(V,0), last(V, -1), path(V,0), used(V,0) {}

    int addEdge(int x, int y, Flow f, Cost c) {
        cap[E] = f; cost[E] = c; to[E] = y; prev[E] = last[x]; last[x] = E; E++;
        cap[E] = 0; cost[E] = -c; to[E] = x; prev[E] = last[y]; last[y] = E; E++;
        return E - 2;
    }

    pair<Flow, Cost> search(int s, int t) {
        Flow ansf = 0; Cost ansc = 0;
        REP(i,V) used[i] = false;
        REP(i,V) dist[i] = C_INF;

        dist[s] = 0; path[s] = -1; q.push(make_pair(0, s));
        while (!q.empty()) {
            int x = q.top().second; q.pop();
            if (used[x]) continue; used[x] = true;
            for(int e = last[x]; e >= 0; e = prev[e]) if (cap[e] > 0) {
                Cost tmp = dist[x] + cost[e] + pot[x] - pot[to[e]];
                if (tmp < dist[to[e]] && !used[to[e]]) {
                    dist[to[e]] = tmp;
                    path[to[e]] = e;
                    q.push(make_pair(-dist[to[e]], to[e]));
                }
            }
        }
        REP(i,V) pot[i] += dist[i];
        if (used[t]) {
            ansf = F_INF;
            for(int e=path[t]; e >= 0; e=path[to[e^1]]) ansf = min(ansf, cap[e]);
            for(int e=path[t]; e >= 0; e=path[to[e^1]]) { ansc += cost[e] * ansf; cap[e] -= ansf; cap[e^1] += ansf; }
        }
        return make_pair(ansf, ansc);
    }
    pair<Flow, Cost> minCostFlow(int s, int t) {
        Flow ansf = 0; Cost ansc = 0;
        while (1) {
            pair<Flow, Cost> p = search(s, t);
            if (!used[t]) break;
            ansf += p.first; ansc += p.second;
        }
        return make_pair(ansf, ansc);
    }
};



const int MN = 111*111*2;
long long f[111][111], c[111][111];
int id_u[MN], id_v[MN], edges[MN];

int main() {
    int n, m, k, s, t;
    while (cin >> n >> m >> k >> s >> t) {
        MinCostFlow<long long, long long> mcf(n+1, m*2+2);

        mcf.addEdge(0, s, k, 0);

        memset(f, 0, sizeof f);
        FOR(i,1,m) {
            int u, v;
            cin >> u >> v;
            cin >> c[u][v] >> f[u][v];
            c[v][u] = c[u][v]; f[v][u] = f[u][v];
        }

        m = 0;
        FOR(i,1,n) FOR(j,i+1,n) if (f[i][j]) {
            edges[++m] = mcf.addEdge(i, j, f[i][j], c[i][j]); id_u[m] = i; id_v[m] = j;
            edges[++m] = mcf.addEdge(j, i, f[i][j], c[i][j]); id_u[m] = j; id_v[m] = i;
        }

        pair<long long, long long> res = mcf.minCostFlow(0, t);

        if (res.first < k) {
            cout << -1 << endl;
            continue;
        }
        cout << res.second << endl;

        FOR(i,1,m/2) {
            int u = id_u[i], v = id_v[i];
            int f_xuoi = f[u][v] - mcf.cap[edges[i*2-1]];
            int f_nguoc = f[v][u] - mcf.cap[edges[i*2]];

            int t = min(f_xuoi, f_nguoc);
            f_xuoi -= t;
            f_nguoc -= t;

            if (f_xuoi > 0) {
                cout << id_u[i*2-1] << ' ' << id_v[i*2-1] << ' ' << f_xuoi << endl;
            }
            if (f_nguoc > 0) {
                cout << id_u[i*2] << ' ' << id_v[i*2] << ' ' << f_nguoc << endl;
            }
        }
        cout << "0 0 0" << endl;
    }
}

Code mẫu của hieult

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

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <string> vs;


#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 FIT(it, v) for (typeof((v).begin())it = (v).begin(); it != (v).end(); ++it)
#define FITD(it, v) for (typeof((v).rbegin())it = (v).rbegin(); it != (v).rend(); ++it)

#define VAR(a, b) typeof(b) a(b)
#define ALL(v) (v).begin(), (v).end()
#define SET(a, x) memset((a), (x), sizeof(a))
#define SIZE(a) ((int)(a).size())

#define EXIST(a, b) (find(ALL(a), (b)) != (a).end())
#define SORT(x) sort(ALL(x))
#define GSORT(x) sort(ALL(x), greater<typeof(*((x).begin()))>())
#define UNIQUE(v) SORT(v); (v).resize(unique(ALL(v)) - (v).begin())
#define ENUM(v) FIT(it, (v)) cout << *it << " "; cout << endl

#define PF push_front
#define PB push_back
#define MP make_pair
#define F first
#define S second
// bit operater
int BIT(int i,ll x) { return(x&(1<<i));}
ll ONBIT(int i,ll x){ return(x|(1<<i));}
ll OFFBIT(int i,ll x){return (x& ~(1<<i));}
ll FLIPBIT(int i,ll x){return (x^(1<<i));}
ll NUMBIT(ll x) {return __builtin_popcount(x);}
// math
template<class T> T gcd(T a, T b){ T r; while (b != 0) { r = a % b; a = b; b = r; } return a;}
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
ll POW(ll x,ll y,ll base)
{
    if (!y) return 1;
    ll tg=POW(x,y/2,base);
    tg=(tg*tg)%base;
    if (y%2) return (tg*x)%base; else return tg;
}
ull Multy(ull a,ull b,ull base)
{   
    if (!a || !b) return 0;
    if (a<=ULLONG_MAX/b) return(a*b)%base;
    ull x=Multy(a,b/2,base);
    x=(x+x)%base;
    if (b%2==1) x=(x+a)%base;
    return(x);
}
ll Com(int k,int n,int base)
{
    if (k==0) return 1;
    ll x=1,tg=1,y;
    FOR(i,n-k+1,n) x=(x*i)%base;
    FOR(i,1,k) tg=(tg*i)%base;
    y=POW(tg,base-2,base);
    return(x*y%base);   
}
//int primes[5500000];
//bool nto[10000000];
//int numprime=0;
//void sang(ll n)
//{ 
//  FOR(i,0,n) nto[i]=true;
//  nto[1]=false;
//  nto[0]=false;
//  for(ll i=2;i<=n;i++)
//  if (nto[i])
//  {
//      numprime++;
//      primes[numprime]=i;
//      for(ll j=i*i;j<=n;j+=i) nto[j]=false;
//  }
//}
//ll EulerPhi(ll n)
//{
//  ll PF_idx=1;
//  ll PF=primes[PF_idx];
//  ll ans=n;
//  while (PF*PF<=n)
//  {
//      if (n%PF==0) ans-=ans/PF;
//      while (n%PF==0) n/=PF;
//      PF=primes[++PF_idx];
//  }
//  if (n!=1) ans-=ans/n;
//  return ans;
//}
const int maxv=500;
const int maxe=maxv*maxv;
const int inf = (int)1e9 + 5;
const ll linf = (ll)1e16 + 5;
const int dr[] = {-1, 0, +1, 0};
const int dc[] = {0, +1, 0, -1};


struct MincostFlow {
    int n, s, t, E, adj[maxe], next[maxe], last[maxv], which[maxv];
    ll totalCost, totalFlow, cap[maxe], flow[maxe], cost[maxe], pot[maxe], dist[maxv];

    void init(int _n, int _s, int _t) {
        n = _n; s = _s; t = _t;
        SET(last, -1); E = 0;
    }

    void add(int u, int v, ll ca, ll co) {
        adj[E] = v; cap[E] = ca; flow[E] = 0; cost[E] = +co; next[E] = last[u]; last[u] = E++;
        adj[E] = u; cap[E] =  0; flow[E] = 0; cost[E] = -co; next[E] = last[v]; last[v] = E++;
    }

    void bellman() {
        bool stop = false;
        SET(pot, 0);

        while (!stop) {
            stop = true;
            FOR(u,0,n-1) for (int e = last[u]; e != -1; e = next[e]) if (flow[e] < cap[e]) {
                int v = adj[e];
                if (pot[v] > pot[u] + cost[e]) {
                    pot[v] = pot[u] + cost[e];
                    stop = false;
                }
            }
        }
    }

    bool dijkstra() {
        typedef pair<ll, int> node;
        priority_queue<node, vector<node>, greater<node> > que;

        FOR(u,0,n-1) dist[u] = linf;
        dist[s] = 0;
        que.push(MP(0, s));

        while (!que.empty()) {
            ll dnow = que.top().F;
            int u = que.top().S;
            que.pop();

            if (dnow > dist[u]) continue;

            for (int e = last[u]; e != -1; e = next[e]) if (flow[e] < cap[e]) {
                int v = adj[e];
                ll dnext = dnow + cost[e] + pot[u] - pot[v];

                if (dist[v] > dnext) {
                    dist[v] = dnext;
                    which[v] = e;
                    que.push(MP(dnext, v));
                }
            }
        }

        return dist[t] < linf;
    }

    bool maxflow(ll desireFlow = linf) {
        totalCost = totalFlow = 0;
        bellman();

        while (totalFlow < desireFlow) {
            if (!dijkstra()) return false;

            ll delta = desireFlow - totalFlow;
            for (int v = t, e = which[v]; v != s; v = adj[e ^ 1], e = which[v]) delta = min(delta, cap[e] - flow[e]);
            for (int v = t, e = which[v]; v != s; v = adj[e ^ 1], e = which[v]) {
                flow[e] += delta;
                flow[e ^ 1] -= delta;
            }

            totalFlow += delta;
            totalCost += delta * (dist[t] - pot[s] + pot[t]);

            FOR(u,0,n-1) pot[u] += dist[u];
        }

        return true;
    }
} mcf;

//------------------------
const char IN[] = "_.in";
const char OUT[] = "_.out";
const int maxn=310;
const int base=1e9+7;
int test;
//cout<<setprecision(7)<<fixed<<"Case "<<I<<": "
int n,m,k,s,f;
int c[maxn][maxn],d[maxn][maxn];

int main() {
  //freopen(IN, "r", stdin);
  //freopen(OUT, "w", stdout);    
  int u,v,cost,cap;
  cin>>n>>m>>k>>s>>f;
  mcf.init(n+2,0,n+1) ;
  mcf.add(0,s,k,0);
  mcf.add(f,n+1,k,0);

  SET(c,-1);
  SET(d,-1);

  FOR(i,0,m-1)
  {
    cin>>u>>v>>cost>>cap;
    c[u][v]=c[v][u]=cost;
    d[u][v]=d[v][u]=cap;
  }

  FOR(i,1,n)
  FOR(j,i+1,n)
  if (c[i][j]!=-1)
  {
        mcf.add(i,j,d[i][j],c[i][j]);
        mcf.add(j,i,d[j][i],c[j][i]);
  }
  mcf.maxflow();

  if (mcf.totalFlow<k)
  {
        cout<<-1;
        return 0;
  }
  else
  {
        cout<<mcf.totalCost<<endl;
        FOR(i,0,mcf.E/2)
        if (mcf.flow[2*i] && mcf.adj[2*i+1]!=0 && mcf.adj[i+i]!=n+1)
        {
            cout<<mcf.adj[i*2+1]<<" "<<mcf.adj[i+i]<<" "<<mcf.flow[i+i]<<endl;
        }
        cout<<"0 0 0"<<endl;
  }
  return 0;
}

Code mẫu của ll931110

program MINCOST;
const
  input  = '';
  output = '';
  maxn = 103;
var
  d,c,f: array[1..maxn,1..maxn] of longint;
  n,m,k,s,t,count: longint;

  inqueue: array[1..maxn] of boolean;
  queue: array[0..maxn] of longint;

  best,trace: array[1..maxn] of longint;

  front,rear: longint;
  fi,fo: text;

procedure openfile;
begin
  assign(fi, input);  reset(fi);
  assign(fo, output);  rewrite(fo);
end;

procedure init;
var
  i,u,v: longint;
begin
  readln(fi, n, m, k, s, t);
  fillchar(c, sizeof(c), 0);
  fillchar(f, sizeof(f), 0);

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

function FindPath: boolean;
var
  u,v,tmp: longint;
  nt: longint;
begin
  fillchar(trace, sizeof(trace), 0);
  for u := 1 to n do best[u] := high(longint);
  best[s] := 0;

  fillchar(inqueue, sizeof(inqueue), false);
  inqueue[s] := true;
  nt := 1;
  front := 1;  rear := 1;  queue[1] := s;

  repeat
    u := queue[front];
    front := (front + 1) mod maxn;
    inqueue[u] := false;
    dec(nt);

    for v := 1 to n do if c[u,v] > f[u,v] then
      begin
        if f[u,v] = 0 then tmp := d[u,v] else tmp := d[u,v] * f[u,v] div abs(f[u,v]);
        if best[v] > best[u] + tmp then
          begin
            best[v] := best[u] + tmp;
            trace[v] := u;
            if not inqueue[v] then
              begin
                inqueue[v] := true;
                inc(nt);
                rear := (rear + 1) mod maxn;
                queue[rear] := v;
              end;
          end;
      end;
  until nt = 0;

  FindPath := (best[t] < high(longint));
end;

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

  while v <> s do
    begin
      u := trace[v];
      if f[u,v] >= 0 then p := c[u,v] - f[u,v] else p := f[v,u];
      if delta > p then delta := p;
      v := u;
    end;

  if delta > k - count then delta := k - count;
  count := count + delta;

  v := t;
  while v <> s do
    begin
      u := trace[v];
      f[u,v] := f[u,v] + delta;
      f[v,u] := f[v,u] - delta;
      v := u;
    end;
end;

procedure solve;
begin
  count := 0;
  repeat
    if not FindPath then break;
    IncFlow;
  until count = k;
end;

procedure printresult;
var
  i,j,cost: longint;
begin
  if count < k then writeln(fo, -1) else
    begin
      cost := 0;
      for i := 1 to n do
        for j := 1 to n do
          if f[i,j] > 0 then cost := cost + d[i,j] * f[i,j];

      writeln(fo, cost);
      for i := 1 to n do
        for j := 1 to n do
          if f[i,j] > 0 then writeln(fo, i, ' ', j, ' ', f[i,j]);

      writeln(fo, 0, ' ', 0, ' ', 0);
    end;
end;

procedure closefile;
begin
  close(fo);  close(fi);
end;

begin
  openfile;
  init;
  solve;
  printresult;
  closefile;
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);inq[s]=true;d[s]=0;
        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));
    }
};
int capa[MAX][MAX],cost[MAX][MAX];
int n,m,k,s,t;
MaxFlowMinCost g;
void loadgraph(void) {
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&k);
    scanf("%d",&s);
    scanf("%d",&t);
    memset(capa,-1,sizeof capa);
    REP(i,m) {
        int u,v,c,d;
        scanf("%d",&u);
        scanf("%d",&v);
        scanf("%d",&c);
        scanf("%d",&d);
        capa[u][v]=d;
        cost[u][v]=c;
        capa[v][u]=d;
        cost[v][u]=c;
    }
    g=MaxFlowMinCost(n+1);
    FOR(u,1,n) FOR(v,1,n) if (capa[u][v]>=0) g.addedge(u,v,capa[u][v],cost[u][v]);
    g.addedge(n+1,s,k,0);   
}
void process(void) {
    ii res=g.getflow(n+1,t);    
    if (res.fi<k) {
        printf("-1");
        return;
    }   
    printf("%d\n",res.se);  
    int totcost=0;  
    REP(i,g.e.size()) if (i%2==0 && g.e[i].flow>0) {
        if (g.e[i].from<=n) printf("%d %d %d\n",g.e[i].from,g.e[i].to,g.e[i].flow);     
        totcost+=g.e[i].cost*g.e[i].flow;
    }   
    assert(res==ii(k,totcost));
    printf("0 0 0");
}
int main(void) {
#ifndef ONLINE_JUDGE
    freopen("tmp.txt","r",stdin);
    printf("START\n");
#endif
    loadgraph();
    process();
    return 0;
}

Code mẫu của khuc_tuan

#include "stdio.h"
#include "string.h"

int n, flow, start, finish, m;
int cap[111][111], cost[111][111], f[111][111];
int fx[111], dt;
bool visited[111], daxong;

bool dfs(int i) {
    if(daxong) return false;
    visited[i] = true;
    if(i==finish) { --flow; return daxong = true; }
    for(int j=1;j<=n;++j) {
        if(f[i][j]<cap[i][j] && !visited[j]) {
            if(fx[i]+cost[i][j]-fx[j]==0) {
                if(dfs(j)) { ++f[i][j]; return true; }
            }
            else dt <?= fx[i]+cost[i][j]-fx[j];
        }
        if(f[j][i]>0 && !visited[j]) {
            if(fx[j]+cost[j][i]-fx[i]==0) {
                if(dfs(j)) { --f[j][i]; return true; }
            }
            else dt <?= -(fx[j]+cost[j][i]-fx[i]);
        }
    }
    return false;
}

int main() {
    int u, v, c, d;
    scanf("%d%d%d%d%d",&n,&m,&flow,&start,&finish);
    for(int i=0;i<m;++i) {
        scanf("%d%d%d%d",&u,&v,&c,&d);
        cap[u][v] = cap[v][u] = d;
        cost[u][v] = cost[v][u] = c;
    }
    for(int i=0;i<50000 && flow>0;++i) {
        memset( visited, false, sizeof(visited));
        daxong = false;
        dt = 1000000000;
        if(!dfs(start))
            for(int i=1;i<=n;++i) if(!visited[i]) fx[i] += dt;
    }
    if(flow>0) printf("-1");
    else {
        int res = 0;
        for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) res += f[i][j] * cost[i][j];
        printf("%d\n",res);
        for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) 
            if(f[i][j]>0) printf("%d %d %d\n",i, j, f[i][j]);
        printf("0 0 0");
    }
    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.