Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- This file contains the code from "Algorithms in C++, Third Edition,
- Part 5," by Robert Sedgewick, and is covered under the copyright
- and warranty notices in that book. Permission is granted for this
- code to be used for educational purposes in association with the text,
- and for other uses not covered by copyright laws, provided that
- the following notice is included with the code:
- "This code is from "Algorithms in C++, Third Edition,"
- by Robert Sedgewick, Addison-Wesley, 2002."
- Commercial uses of this code require the explicit written
- permission of the publisher. Send your request for permission,
- stating clearly what code you would like to use, and in what
- specific way, to: [email protected]
- ----------
- CHAPTER 17. Graph Properties and Types
- -----
- struct Edge
- { int v, w;
- Edge(int v = -1, int w = -1) : v(v), w(w) { }
- };
- class GRAPH
- { private:
- // Implementation-dependent code
- public:
- GRAPH(int, bool);
- ~GRAPH();
- int V() const;
- int E() const;
- bool directed() const;
- int insert(Edge);
- int remove(Edge);
- bool edge(int, int);
- class adjIterator
- {
- public:
- adjIterator(const GRAPH &, int);
- int beg();
- int nxt();
- bool end();
- };
- };
- -----
- template <class Graph>
- vector <Edge> edges(Graph &G)
- { int E = 0;
- vector <Edge> a(G.E());
- for (int v = 0; v < G.V(); v++)
- {
- typename Graph::adjIterator A(G, v);
- for (int w = A.beg(); !A.end(); w = A.nxt())
- if (G.directed() || v < w)
- a[E++] = Edge(v, w);
- }
- return a;
- }
- -----
- template <class Graph>
- void IO<Graph>::show(const Graph &G)
- {
- for (int s = 0; s < G.V(); s++)
- {
- cout.width(2); cout << s << ":";
- typename Graph::adjIterator A(G, s);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- { cout.width(2); cout << t << " "; }
- cout << endl;
- }
- }
- -----
- template <class Graph>
- class IO
- {
- public:
- static void show(const Graph &);
- static void scanEZ(Graph &);
- static void scan(Graph &);
- };
- -----
- template <class Graph>
- class CC
- {
- private:
- // implementation-dependent code
- public:
- CC(const Graph &);
- int count();
- bool connect(int, int);
- };
- -----
- #include <iostream.h>
- #include <stdlib.h>
- #include "GRAPH.cc"
- #include "IO.cc"
- #include "CC.cc"
- main(int argc, char *argv[])
- { int V = atoi(argv[1]);
- GRAPH G(V);
- IO<GRAPH>::scan(G);
- if (V < 20) IO<GRAPH>::show(G);
- cout << G.E() << " edges ";
- CC<GRAPH> Gcc(G);
- cout << Gcc.count() << " components" << endl;
- }
- -----
- class DenseGRAPH
- { int Vcnt, Ecnt; bool digraph;
- vector <vector <bool> > adj;
- public:
- DenseGRAPH(int V, bool digraph = false) :
- adj(V), Vcnt(V), Ecnt(0), digraph(digraph)
- {
- for (int i = 0; i < V; i++)
- adj[i].assign(V, false);
- }
- int V() const { return Vcnt; }
- int E() const { return Ecnt; }
- bool directed() const { return digraph; }
- void insert(Edge e)
- { int v = e.v, w = e.w;
- if (adj[v][w] == false) Ecnt++;
- adj[v][w] = true;
- if (!digraph) adj[w][v] = true;
- }
- void remove(Edge e)
- { int v = e.v, w = e.w;
- if (adj[v][w] == true) Ecnt--;
- adj[v][w] = false;
- if (!digraph) adj[w][v] = false;
- }
- bool edge(int v, int w) const
- { return adj[v][w]; }
- class adjIterator;
- friend class adjIterator;
- };
- -----
- class DenseGRAPH::adjIterator
- { const DenseGRAPH &G;
- int i, v;
- public:
- adjIterator(const DenseGRAPH &G, int v) :
- G(G), v(v), i(-1) { }
- int beg()
- { i = -1; return nxt(); }
- int nxt()
- {
- for (i++; i < G.V(); i++)
- if (G.adj[v][i] == true) return i;
- return -1;
- }
- bool end()
- { return i >= G.V(); }
- };
- -----
- class SparseMultiGRAPH
- { int Vcnt, Ecnt; bool digraph;
- struct node
- { int v; node* next;
- node(int x, node* t) { v = x; next = t; }
- };
- typedef node* link;
- vector <link> adj;
- public:
- SparseMultiGRAPH(int V, bool digraph = false) :
- adj(V), Vcnt(V), Ecnt(0), digraph(digraph)
- { adj.assign(V, 0); }
- int V() const { return Vcnt; }
- int E() const { return Ecnt; }
- bool directed() const { return digraph; }
- void insert(Edge e)
- { int v = e.v, w = e.w;
- adj[v] = new node(w, adj[v]);
- if (!digraph) adj[w] = new node(v, adj[w]);
- Ecnt++;
- }
- void remove(Edge e);
- bool edge(int v, int w) const;
- class adjIterator;
- friend class adjIterator;
- };
- -----
- class SparseMultiGRAPH::adjIterator
- { const SparseMultiGRAPH &G;
- int v;
- link t;
- public:
- adjIterator(const SparseMultiGRAPH &G, int v) :
- G(G), v(v) { t = 0; }
- int beg()
- { t = G.adj[v]; return t ? t->v : -1; }
- int nxt()
- { if (t) t = t->next; return t ? t->v : -1; }
- bool end()
- { return t == 0; }
- };
- -----
- template <class Graph> class DEGREE
- { const Graph &G;
- vector <int> degree;
- public:
- DEGREE(const Graph &G) : G(G), degree(G.V(), 0)
- {
- for (int v = 0; v < G.V(); v++)
- { typename Graph::adjIterator A(G, v);
- for (int w = A.beg(); !A.end(); w = A.nxt())
- degree[v]++;
- }
- }
- int operator[](int v) const
- { return degree[v]; }
- };
- -----
- static void randE(Graph &G, int E)
- {
- for (int i = 0; i < E; i++)
- {
- int v = int(G.V()*rand()/(1.0+RAND_MAX));
- int w = int(G.V()*rand()/(1.0+RAND_MAX));
- G.insert(Edge(v,w));
- }
- }
- -----
- static void randG(Graph &G, int E)
- { double p = 2.0*E/G.V()/(G.V()-1);
- for (int i = 0; i < G.V(); i++)
- for (int j = 0; j < i; j++)
- if (rand() < p*RAND_MAX)
- G.insert(Edge(i, j));
- }
- -----
- #include "ST.cc"
- template <class Graph>
- void IO<Graph>::scan(Graph &G)
- { string v, w;
- ST st;
- while (cin >> v >> w)
- G.insert(Edge(st.index(v), st.index(w)));
- }
- -----
- #include <string>
- class ST
- { int N, val;
- struct node
- { int v, d; node* l, *m, *r;
- node(int d) : v(-1), d(d), l(0), m(0), r(0) {}
- };
- typedef node* link;
- link head;
- link indexR(link h, const string &s, int w)
- { int i = s[w];
- if (h == 0) h = new node(i);
- if (i == 0)
- {
- if (h->v == -1) h->v = N++;
- val = h->v;
- return h;
- }
- if (i < h->d) h->l = indexR(h->l, s, w);
- if (i == h->d) h->m = indexR(h->m, s, w+1);
- if (i > h->d) h->r = indexR(h->r, s, w);
- return h;
- }
- public:
- ST() : head(0), N(0) { }
- int index(const string &key)
- { head = indexR(head, key, 0); return val; }
- };
- -----
- template <class Graph> class sPATH
- { const Graph &G;
- vector <bool> visited;
- bool found;
- bool searchR(int v, int w)
- {
- if (v == w) return true;
- visited[v] = true;
- typename Graph::adjIterator A(G, v);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (!visited[t])
- if (searchR(t, w)) return true;
- return false;
- }
- public:
- sPATH(const Graph &G, int v, int w) :
- G(G), visited(G.V(), false)
- { found = searchR(v, w); }
- bool exists() const
- { return found; }
- };
- -----
- bool searchR(int v, int w, int d)
- {
- if (v == w) return (d == 0);
- visited[v] = true;
- typename Graph::adjIterator A(G, v);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (!visited[t])
- if (searchR(t, w, d-1)) return true;
- visited[v] = false;
- return false;
- }
- -----
- template <class Graph> class ePATH
- { Graph G;
- int v, w;
- bool found;
- STACK <int> S;
- int tour(int v);
- public:
- ePATH(const Graph &G, int v, int w) :
- G(G), v(v), w(w)
- { DEGREE<Graph> deg(G);
- int t = deg[v] + deg[w];
- if ((t % 2) != 0) { found = false; return; }
- for (t = 0; t < G.V(); t++)
- if ((t != v) && (t != w))
- if ((deg[t] % 2) != 0)
- { found = false; return; }
- found = true;
- }
- bool exists() const
- { return found; }
- void show();
- };
- -----
- template <class Graph>
- int ePATH<Graph>::tour(int v)
- {
- while (true)
- { typename Graph::adjIterator A(G, v);
- int w = A.beg(); if (A.end()) break;
- S.push(v);
- G.remove(Edge(v, w));
- v = w;
- }
- return v;
- }
- template <class Graph>
- void ePATH<Graph>::show()
- {
- if (!found) return;
- while (tour(v) == v && !S.empty())
- { v = S.pop(); cout << "-" << v; }
- cout << endl;
- }
- ----------
- CHAPTER 18. Graph Search
- -----
- #include <vector>
- template <class Graph> class cDFS
- { int cnt;
- const Graph &G;
- vector <int> ord;
- void searchC(int v)
- {
- ord[v] = cnt++;
- typename Graph::adjIterator A(G, v);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (ord[t] == -1) searchC(t);
- }
- public:
- cDFS(const Graph &G, int v = 0) :
- G(G), cnt(0), ord(G.V(), -1)
- { searchC(v); }
- int count() const { return cnt; }
- int operator[](int v) const { return ord[v]; }
- };
- -----
- template <class Graph> class SEARCH
- {
- protected:
- const Graph &G;
- int cnt;
- vector <int> ord;
- virtual void searchC(Edge) = 0;
- void search()
- { for (int v = 0; v < G.V(); v++)
- if (ord[v] == -1) searchC(Edge(v, v)); }
- public:
- SEARCH (const Graph &G) : G(G),
- ord(G.V(), -1), cnt(0) { }
- int operator[](int v) const { return ord[v]; }
- };
- -----
- template <class Graph>
- class DFS : public SEARCH<Graph>
- { vector<int> st;
- void searchC(Edge e)
- { int w = e.w;
- ord[w] = cnt++; st[e.w] = e.v;
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (ord[t] == -1) searchC(Edge(w, t));
- }
- public:
- DFS(const Graph &G) : SEARCH<Graph>(G),
- st(G.V(), -1) { search(); }
- int ST(int v) const { return st[v]; }
- };
- -----
- template <class Graph> class CC
- { const Graph &G;
- int ccnt;
- vector <int> id;
- void ccR(int w)
- {
- id[w] = ccnt;
- typename Graph::adjIterator A(G, w);
- for (int v = A.beg(); !A.end(); v = A.nxt())
- if (id[v] == -1) ccR(v);
- }
- public:
- CC(const Graph &G) : G(G), ccnt(0), id(G.V(), -1)
- {
- for (int v = 0; v < G.V(); v++)
- if (id[v] == -1) { ccR(v); ccnt++; }
- }
- int count() const { return ccnt; }
- bool connect(int s, int t) const
- { return id[s] == id[t]; }
- };
- -----
- template <class Graph>
- class EULER : public SEARCH<Graph>
- {
- void searchC(Edge e)
- { int v = e.v, w = e.w;
- ord[w] = cnt++;
- cout << "-" << w;
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (ord[t] == -1) searchC(Edge(w, t));
- else if (ord[t] < ord[v])
- cout << "-" << t << "-" << w;
- if (v != w) cout << "-" << v; else cout << endl;
- }
- public:
- EULER(const Graph &G) : SEARCH<Graph>(G)
- { search(); }
- };
- -----
- template <class Graph> class BI
- { const Graph &G;
- bool OK;
- vector <int> vc;
- bool dfsR(int v, int c)
- {
- vc[v] = (c+1) %2;
- typename Graph::adjIterator A(G, v);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (vc[t] == -1)
- { if (!dfsR(t, vc[v])) return false; }
- else if (vc[t] != c) return false;
- return true;
- }
- public:
- BI(const Graph &G) : G(G), OK(true), vc(G.V(),-1)
- {
- for (int v = 0; v < G.V(); v++)
- if (vc[v] == -1)
- if (!dfsR(v, 0)) { OK = false; return; }
- }
- bool bipartite() const { return OK; }
- int color(int v) const { return vc[v]; }
- };
- -----
- template <class Graph>
- class EC : public SEARCH<Graph>
- { int bcnt;
- vector <int> low;
- void searchC(Edge e)
- { int w = e.w;
- ord[w] = cnt++; low[w] = ord[w];
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (ord[t] == -1)
- {
- searchC(Edge(w, t));
- if (low[w] > low[t]) low[w] = low[t];
- if (low[t] == ord[t])
- bcnt++; // w-t is a bridge
- }
- else if (t != e.v)
- if (low[w] > ord[t]) low[w] = ord[t];
- }
- public:
- EC(const Graph &G) : SEARCH<Graph>(G),
- bcnt(0), low(G.V(), -1)
- { search(); }
- int count() const { return bcnt+1; }
- };
- -----
- #include "QUEUE.cc"
- template <class Graph>
- class BFS : public SEARCH<Graph>
- { vector<int> st;
- void searchC(Edge e)
- { QUEUE<Edge> Q;
- Q.put(e);
- while (!Q.empty())
- if (ord[(e = Q.get()).w] == -1)
- { int v = e.v, w = e.w;
- ord[w] = cnt++; st[w] = v;
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (ord[t] == -1) Q.put(Edge(w, t));
- }
- }
- public:
- BFS(Graph &G) : SEARCH<Graph>(G), st(G.V(), -1)
- { search(); }
- int ST(int v) const { return st[v]; }
- };
- -----
- void searchC(Edge e)
- { QUEUE<Edge> Q;
- Q.put(e); ord[e.w] = cnt++;
- while (!Q.empty())
- {
- e = Q.get(); st[e.w] = e.v;
- typename Graph::adjIterator A(G, e.w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (ord[t] == -1)
- { Q.put(Edge(e.w, t)); ord[t] = cnt++; }
- }
- }
- -----
- #include "GQ.cc"
- template <class Graph>
- class PFS : public SEARCH<Graph>
- { vector<int> st;
- void searchC(Edge e)
- { GQ<Edge> Q(G.V());
- Q.put(e); ord[e.w] = cnt++;
- while (!Q.empty())
- {
- e = Q.get(); st[e.w] = e.v;
- typename Graph::adjIterator A(G, e.w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (ord[t] == -1)
- { Q.put(Edge(e.w, t)); ord[t] = cnt++; }
- else
- if (st[t] == -1) Q.update(Edge(e.w, t));
- }
- }
- public:
- PFS(Graph &G) : SEARCH<Graph>(G), st(G.V(), -1)
- { search(); }
- int ST(int v) const { return st[v]; }
- };
- -----
- template <class Item>
- class GQ
- {
- private:
- vector<Item> s; int N;
- public:
- GQ(int maxN) : s(maxN+1), N(0) { }
- int empty() const
- { return N == 0; }
- void put(Item item)
- { s[N++] = item; }
- void update(Item x) { }
- Item get()
- { int i = int(N*rand()/(1.0+RAND_MAX));
- Item t = s[i];
- s[i] = s[N-1];
- s[N-1] = t;
- return s[--N]; }
- };
- ----------
- CHAPTER 19. Digraphs and DAGs
- -----
- template <class inGraph, class outGraph>
- void reverse(const inGraph &G, outGraph &R)
- {
- for (int v = 0; v < G.V(); v++)
- { typename inGraph::adjIterator A(G, v);
- for (int w = A.beg(); !A.end(); w = A.nxt())
- R.insert(Edge(w, v));
- }
- }
- -----
- template <class Graph> class DFS
- { const Graph &G;
- int depth, cnt, cntP;
- vector<int> pre, post;
- void show(char *s, Edge e)
- { for (int i = 0; i < depth; i++) cout << " ";
- cout << e.v << "-" << e.w << s << endl; }
- void dfsR(Edge e)
- { int w = e.w; show(" tree", e);
- pre[w] = cnt++; depth++;
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- { Edge x(w, t);
- if (pre[t] == -1) dfsR(x);
- else if (post[t] == -1) show(" back", x);
- else if (pre[t] > pre[w]) show(" down", x);
- else show(" cross", x);
- }
- post[w] = cntP++; depth--;
- }
- public:
- DFS(const Graph &G) : G(G), cnt(0), cntP(0),
- pre(G.V(), -1), post(G.V(), -1)
- { for (int v = 0; v < G.V(); v++)
- if (pre[v] == -1) dfsR(Edge(v, v)); }
- };
- -----
- template <class tcGraph, class Graph> class TC
- { tcGraph T;
- public:
- TC(const Graph &G) : T(G)
- {
- for (int s = 0; s < T.V(); s++)
- T.insert(Edge(s, s));
- for (int i = 0; i < T.V(); i++)
- for (int s = 0; s < T.V(); s++)
- if (T.edge(s, i))
- for (int t = 0; t < T.V(); t++)
- if (T.edge(i, t))
- T.insert(Edge(s, t));
- }
- bool reachable(int s, int t) const
- { return T.edge(s, t); }
- };
- -----
- template <class Graph> class tc
- { Graph T; const Graph &G;
- void tcR(int v, int w)
- {
- T.insert(Edge(v, w));
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (!T.edge(v, t)) tcR(v, t);
- }
- public:
- tc(const Graph &G) : G(G), T(G.V(), true)
- { for (int v = 0; v < G.V(); v++) tcR(v, v); }
- bool reachable(int v, int w)
- { return T.edge(v, w); }
- };
- -----
- int compressR(link h)
- { STx st;
- if (h == NULL) return 0;
- l = compressR(h->l);
- r = compressR(h->r);
- t = st.index(l, r);
- adj[t].l = l; adj[t].r = r;
- return t;
- }
- -----
- template <class Dag> class dagTS
- { const Dag &D;
- int cnt, tcnt;
- vector<int> pre, post, postI;
- void tsR(int v)
- {
- pre[v] = cnt++;
- typename Dag::adjIterator A(D, v);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (pre[t] == -1) tsR(t);
- post[v] = tcnt; postI[tcnt++] = v;
- }
- public:
- dagTS(const Dag &D) : D(D), tcnt(0), cnt(0),
- pre(D.V(), -1), post(D.V(), -1), postI(D.V(), -1)
- { for (int v = 0; v < D.V(); v++)
- if (pre[v] == -1) tsR(v); }
- int operator[](int v) const { return postI[v]; }
- int relabel(int v) const { return post[v]; }
- };
- -----
- void tsR(int v)
- {
- pre[v] = cnt++;
- for (int w = 0; w < D.V(); w++)
- if (D.edge(w, v))
- if (pre[w] == -1) tsR(w);
- post[v] = tcnt; postI[tcnt++] = v;
- }
- -----
- #include "QUEUE.cc"
- template <class Dag> class dagTS
- { const Dag &D;
- vector<int> in, ts, tsI;
- public:
- dagTS(const Dag &D) : D(D),
- in(D.V(), 0), ts(D.V(), -1), tsI(D.V(), -1)
- { QUEUE<int> Q;
- for (int v = 0; v < D.V(); v++)
- {
- typename Dag::adjIterator A(D, v);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- in[t]++;
- }
- for (int v = 0; v < D.V(); v++)
- if (in[v] == 0) Q.put(v);
- for (int j = 0; !Q.empty(); j++)
- {
- ts[j] = Q.get(); tsI[ts[j]] = j;
- typename Dag::adjIterator A(D, ts[j]);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (--in[t] == 0) Q.put(t);
- }
- }
- int operator[](int v) const { return ts[v]; }
- int relabel(int v) const { return tsI[v]; }
- };
- -----
- template <class tcDag, class Dag> class dagTC
- { tcDag T; const Dag &D;
- int cnt;
- vector<int> pre;
- void tcR(int w)
- {
- pre[w] = cnt++;
- typename Dag::adjIterator A(D, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- {
- T.insert(Edge(w, t));
- if (pre[t] > pre[w]) continue;
- if (pre[t] == -1) tcR(t);
- for (int i = 0; i < T.V(); i++)
- if (T.edge(t, i)) T.insert(Edge(w, i));
- }
- }
- public:
- dagTC(const Dag &D) : D(D), cnt(0),
- pre(D.V(), -1), T(D.V(), true)
- { for (int v = 0; v < D.V(); v++)
- if (pre[v] == -1) tcR(v); }
- bool reachable(int v, int w) const
- { return T.edge(v, w); }
- };
- -----
- template <class Graph> class SC
- { const Graph &G;
- int cnt, scnt;
- vector<int> postI, postR, id;
- void dfsR(const Graph &G, int w)
- {
- id[w] = scnt;
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (id[t] == -1) dfsR(G, t);
- postI[cnt++] = w;
- }
- public:
- SC(const Graph &G) : G(G), cnt(0), scnt(0),
- postI(G.V()), postR(G.V()), id(G.V(), -1)
- { Graph R(G.V(), true);
- reverse(G, R);
- for (int v = 0; v < R.V(); v++)
- if (id[v] == -1) dfsR(R, v);
- postR = postI; cnt = scnt = 0;
- id.assign(G.V(), -1);
- for (int v = G.V()-1; v >= 0; v--)
- if (id[postR[v]] == -1)
- { dfsR(G, postR[v]); scnt++; }
- }
- int count() const { return scnt; }
- bool stronglyreachable(int v, int w) const
- { return id[v] == id[w]; }
- };
- -----
- #include "STACK.cc"
- template <class Graph> class SC
- { const Graph &G;
- STACK<int> S;
- int cnt, scnt;
- vector<int> pre, low, id;
- void scR(int w)
- { int t;
- int min = low[w] = pre[w] = cnt++;
- S.push(w);
- typename Graph::adjIterator A(G, w);
- for (t = A.beg(); !A.end(); t = A.nxt())
- {
- if (pre[t] == -1) scR(t);
- if (low[t] < min) min = low[t];
- }
- if (min < low[w]) { low[w] = min; return; }
- do
- { id[t = S.pop()] = scnt; low[t] = G.V(); }
- while (t != w);
- scnt++;
- }
- public:
- SC(const Graph &G) : G(G), cnt(0), scnt(0),
- pre(G.V(), -1), low(G.V()), id(G.V())
- { for (int v = 0; v < G.V(); v++)
- if (pre[v] == -1) scR(v); }
- int count() const { return scnt; }
- bool stronglyreachable(int v, int w) const
- { return id[v] == id[w]; }
- };
- -----
- void scR(int w)
- { int v;
- pre[w] = cnt++;
- S.push(w); path.push(w);
- typename Graph::adjIterator A(G, w);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- if (pre[t] == -1) scR(t);
- else if (id[t] == -1)
- while (pre[path.top()] > pre[t]) path.pop();
- if (path.top() == w) path.pop(); else return;
- do { id[v = S.pop()] = scnt; } while (v != w);
- scnt++;
- }
- -----
- template <class Graph> class TC
- { const Graph &G; DenseGRAPH *K;
- dagTC<DenseGRAPH, Graph> *Ktc;
- SC<Graph> *Gsc;
- public:
- TC(const Graph &G) : G(G)
- {
- Gsc = new SC<Graph>(G);
- K = new DenseGRAPH(Gsc->count(), true);
- for (int v = 0; v < G.V(); v++)
- { typename Graph::adjIterator A(G, v);
- for (int t = A.beg(); !A.end(); t = A.nxt())
- K->insert(Edge(Gsc->ID(v), Gsc->ID(t))); }
- Ktc = new dagTC<DenseGRAPH, Graph>(*K);
- }
- ~TC() { delete K; delete Ktc; delete Gsc; }
- bool reachable(int v, int w)
- { return Ktc->reachable(Gsc->ID(v), Gsc->ID(w));}
- };
- ----------
- CHAPTER 20. Minimum Spanning Trees
- -----
- class EDGE
- {
- public:
- EDGE(int, int, double);
- int v() const;
- int w() const;
- double wt() const;
- bool from(int) const;
- int other(int) const;
- };
- template <class Edge> class GRAPH
- {
- public:
- GRAPH(int, bool);
- ~GRAPH();
- int V() const;
- int E() const;
- bool directed() const;
- int insert(Edge *);
- int remove(Edge *);
- Edge *edge(int, int);
- class adjIterator
- {
- public:
- adjIterator(const GRAPH &, int);
- Edge *beg();
- Edge *nxt();
- bool end();
- };
- };
- -----
- template <class Graph, class Edge>
- vector <Edge *> edges(const Graph &G)
- { int E = 0;
- vector <Edge *> a(G.E());
- for (int v = 0; v < G.V(); v++)
- {
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- if (e->from(v)) a[E++] = e;
- }
- return a;
- }
- -----
- template <class Edge> class DenseGRAPH
- { int Vcnt, Ecnt; bool digraph;
- vector <vector <Edge *> > adj;
- public:
- DenseGRAPH(int V, bool digraph = false) :
- adj(V), Vcnt(V), Ecnt(0), digraph(digraph)
- {
- for (int i = 0; i < V; i++)
- adj[i].assign(V, 0);
- }
- int V() const { return Vcnt; }
- int E() const { return Ecnt; }
- bool directed() const { return digraph; }
- void insert(Edge *e)
- { int v = e->v(), w = e->w();
- if (adj[v][w] == 0) Ecnt++;
- adj[v][w] = e;
- if (!digraph) adj[w][v] = e;
- }
- void remove(Edge *e)
- { int v = e->v(), w = e->w();
- if (adj[v][w] != 0) Ecnt--;
- adj[v][w] = 0;
- if (!digraph) adj[w][v] = 0;
- }
- Edge* edge(int v, int w) const
- { return adj[v][w]; }
- class adjIterator;
- friend class adjIterator;
- };
- -----
- template <class Edge>
- class DenseGRAPH<Edge>::adjIterator
- { const DenseGRAPH<Edge> &G;
- int i, v;
- public:
- adjIterator(const DenseGRAPH<Edge> &G, int v) :
- G(G), v(v), i(0) { }
- Edge *beg()
- { i = -1; return nxt(); }
- Edge *nxt()
- {
- for (i++; i < G.V(); i++)
- if (G.edge(v, i)) return G.adj[v][i];
- return 0;
- }
- bool end() const
- { return i >= G.V(); }
- };
- -----
- template <class Edge> class SparseMultiGRAPH
- { int Vcnt, Ecnt; bool digraph;
- struct node
- { Edge* e; node* next;
- node(Edge* e, node* next): e(e), next(next) {}
- };
- typedef node* link;
- vector <link> adj;
- public:
- SparseMultiGRAPH(int V, bool digraph = false) :
- adj(V), Vcnt(V), Ecnt(0), digraph(digraph) { }
- int V() const { return Vcnt; }
- int E() const { return Ecnt; }
- bool directed() const { return digraph; }
- void insert(Edge *e)
- {
- adj[e->v()] = new node(e, adj[e->v()]);
- if (!digraph)
- adj[e->w()] = new node(e, adj[e->w()]);
- Ecnt++;
- }
- class adjIterator;
- friend class adjIterator;
- };
- -----
- template <class Graph, class Edge> class MST
- { const Graph &G;
- vector<double> wt;
- vector<Edge *> fr, mst;
- public:
- MST(const Graph &G) : G(G),
- mst(G.V()), wt(G.V(), G.V()), fr(G.V())
- { int min = -1;
- for (int v = 0; min != 0; v = min)
- {
- min = 0;
- for (int w = 1; w < G.V(); w++)
- if (mst[w] == 0)
- { double P; Edge* e = G.edge(v, w);
- if (e)
- if ((P = e->wt()) < wt[w])
- { wt[w] = P; fr[w] = e; }
- if (wt[w] < wt[min]) min = w;
- }
- if (min) mst[min] = fr[min];
- }
- }
- void show()
- { for (int v = 1; v < G.V(); v++)
- if (mst[v]) mst[v]->show();}
- };
- -----
- template <class Graph, class Edge> class MST
- { const Graph &G;
- vector<double> wt;
- vector<Edge *> fr, mst;
- void pfs(int s)
- { PQi<double> pQ(G.V(), wt);
- pQ.insert(s);
- while (!pQ.empty())
- { int v = pQ.getmin();
- mst[v] = fr[v];
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- { double P = e->wt(); int w = e->other(v);
- if (fr[w] == 0)
- { wt[w] = P; pQ.insert(w); fr[w] = e; }
- else if (mst[w] == 0 && P < wt[w])
- { wt[w] = P; pQ.lower(w); fr[w] = e; }
- }
- }
- }
- public:
- MST(Graph &G) : G(G),
- fr(G.V()), mst(G.V()), wt(G.V(), -1)
- { for (int v = 0; v < G.V(); v++)
- if (mst[v] == 0) pfs(v); }
- };
- -----
- template <class Graph, class Edge, class EdgePtr>
- class MST
- { const Graph &G;
- vector<EdgePtr> a, mst;
- UF uf;
- public:
- MST(Graph &G) : G(G), uf(G.V()), mst(G.V())
- { int V = G.V(), E = G.E();
- a = edges<Graph, Edge, EdgePtr>(G);
- sort<EdgePtr>(a, 0, E-1);
- for (int i = 0, k = 1; i < E && k < V; i++)
- if (!uf.find(a[i]->v, a[i]->w))
- { uf.unite(a[i]->v, a[i]->w);
- mst[k++] = a[i]; }
- }
- };
- -----
- template <class Graph, class Edge> class MST
- { const Graph &G;
- vector<Edge *> a, b, mst;
- UF uf;
- public:
- MST(const Graph &G): G(G), uf(G.V()), mst(G.V()+1)
- { a = edges<Graph, Edge>(G);
- int N, k = 1;
- for (int E = a.size(); E != 0; E = N)
- { int h, i, j;
- b.assign(G.V(), 0);
- for (h = 0, N = 0; h < E; h++)
- { Edge *e = a[h];
- i = uf.find(e->v()), j = uf.find(e->w());
- if (i == j) continue;
- if (!b[i] || e->wt() < b[i]->wt()) b[i] = e;
- if (!b[j] || e->wt() < b[j]->wt()) b[j] = e;
- a[N++] = e;
- }
- for (h = 0; h < G.V(); h++)
- if (b[h])
- if (!uf.find(i = b[h]->v(), j = b[h]->w()))
- { uf.unite(i, j); mst[k++] = b[h]; }
- }
- }
- };
- -----
- template <class keyType> class PQi
- { int d, N;
- vector<int> pq, qp;
- const vector<keyType> &a;
- void exch(int i, int j)
- { int t = pq[i]; pq[i] = pq[j]; pq[j] = t;
- qp[pq[i]] = i; qp[pq[j]] = j; }
- void fixUp(int k)
- { while (k > 1 && a[pq[(k+d-2)/d]] > a[pq[k]])
- { exch(k, (k+d-2)/d); k = (k+d-2)/d; } }
- void fixDown(int k, int N)
- { int j;
- while ((j = d*(k-1)+2) <= N)
- {
- for (int i = j+1; i < j+d && i <= N; i++)
- if (a[pq[j]] > a[pq[i]]) j = i;
- if (!(a[pq[k]] > a[pq[j]])) break;
- exch(k, j); k = j;
- }
- }
- public:
- PQi(int N, const vector<keyType> &a, int d = 3) :
- a(a), pq(N+1, 0), qp(N+1, 0), N(0), d(d) { }
- int empty() const { return N == 0; }
- void insert(int v)
- { pq[++N] = v; qp[v] = N; fixUp(N); }
- int getmin()
- { exch(1, N); fixDown(1, N-1); return pq[N--]; }
- void lower(int k)
- { fixUp(qp[k]); }
- };
- ----------
- CHAPTER 21. Shortest Paths
- -----
- template <class Graph, class Edge> class SPT
- { const Graph &G;
- vector<double> wt;
- vector<Edge *> spt;
- public:
- SPT(const Graph &G, int s) : G(G),
- spt(G.V()), wt(G.V(), G.V())
- { PQi<double> pQ(G.V(), wt);
- for (int v = 0; v < G.V(); v++) pQ.insert(v);
- wt[s] = 0.0; pQ.lower(s);
- while (!pQ.empty())
- { int v = pQ.getmin(); // wt[v] = 0.0;
- if (v != s && spt[v] == 0) return;
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- { int w = e->w();
- double P = wt[v] + e->wt();
- if (P < wt[w])
- { wt[w] = P; pQ.lower(w); spt[w] = e; }
- }
- }
- }
- Edge *pathR(int v) const { return spt[v]; }
- double dist(int v) const { return wt[v]; }
- };
- -----
- template <class Graph, class Edge> class SPall
- {
- public:
- SPall(const Graph &);
- Edge *path(int, int) const;
- Edge *pathR(int, int) const;
- double dist(int, int) const;
- };
- -----
- template <class Graph, class Edge>
- double diameter(Graph &G)
- { int vmax = 0, wmax = 0;
- allSP<Graph, Edge> all(G);
- for (int v = 0; v < G.V(); v++)
- for (int w = 0; w < G.V(); w++)
- if (all.path(v, w))
- if (all.dist(v, w) > all.dist(vmax, wmax))
- { vmax = v; wmax = w; }
- int v = vmax; cout << v;
- while (v != wmax)
- { v = all.path(v, wmax)->w(); cout << "-" << v; }
- return all.dist(vmax, wmax);
- }
- -----
- #include "SPT.cc"
- template <class Graph, class Edge> class allSP
- { const Graph &G;
- vector< SPT<Graph, Edge> *> A;
- public:
- allSP(const Graph &G) : G(G), A(G.V())
- { for (int s = 0; s < G.V(); s++)
- A[s] = new SPT<Graph, Edge>(G, s); }
- Edge *pathR(int s, int t) const
- { return A[s]->pathR(t); }
- double dist(int s, int t) const
- { return A[s]->dist(t); }
- };
- -----
- template <class Graph, class Edge> class allSP
- { const Graph &G;
- vector <vector <Edge *> > p;
- vector <vector <double> > d;
- public:
- allSP(const Graph &G) : G(G), p(G.V()), d(G.V())
- { int V = G.V();
- for (int i = 0; i < V; i++)
- { p[i].assign(V, 0); d[i].assign(V, V); }
- for (int s = 0; s < V; s++)
- for (int t = 0; t < V; t++)
- if (G.edge(s, t))
- { p[s][t] = G.edge(s, t);
- d[s][t] = G.edge(s, t)->wt(); }
- for (int s = 0; s < V; s++) d[s][s] = 0;
- for (int i = 0; i < V; i++)
- for (int s = 0; s < V; s++)
- if (p[s][i])
- for (int t = 0; t < V; t++)
- if (s != t)
- if (d[s][t] > d[s][i] + d[i][t])
- { p[s][t] = p[s][i];
- d[s][t] = d[s][i] + d[i][t]; }
- }
- Edge *path(int s, int t) const
- { return p[s][t]; }
- double dist(int s, int t) const
- { return d[s][t]; }
- };
- -----
- #include "dagTS.cc"
- template <class Graph, class Edge> class LPTdag
- { const Graph &G;
- vector<double> wt;
- vector<Edge *> lpt;
- public:
- LPTdag(const Graph &G) : G(G),
- lpt(G.V()), wt(G.V(), 0)
- { int j, w;
- dagTS<Graph> ts(G);
- for (int v = ts[j = 0]; j < G.V(); v = ts[++j])
- { typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- if (wt[w = e->w()] < wt[v] + e->wt())
- { wt[w] = wt[v] + e->wt(); lpt[w] = e; }
- }
- }
- Edge *pathR(int v) const { return lpt[v]; }
- double dist(int v) const { return wt[v]; }
- };
- -----
- template <class Graph, class Edge> class allSPdag
- { const Graph &G;
- vector <vector <Edge *> > p;
- vector <vector <double> > d;
- void dfsR(int s)
- { typename Graph::adjIterator A(G, s);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- { int t = e->w(); double w = e->wt();
- if (d[s][t] > w)
- { d[s][t] = w; p[s][t] = e; }
- if (p[t][t] == 0) dfsR(t);
- for (int i = 0; i < G.V(); i++)
- if (p[t][i])
- if (d[s][i] > w + d[t][i])
- { d[s][i] = w + d[t][i]; p[s][i] = e; }
- }
- }
- public:
- allSPdag(const Graph &G) : G(G),
- p(G.V()), d(G.V())
- { int V = G.V();
- for (int i = 0; i < V; i++)
- { p[i].assign(V, 0); d[i].assign(V, V); }
- for (int s = 0; s < V; s++)
- if (p[s][s] == 0) dfsR(s);
- }
- Edge *path(int s, int t) const
- { return p[s][t]; }
- double dist(int s, int t) const
- { return d[s][t]; }
- };
- -----
- #include "GRAPHbasic.cc"
- #include "GRAPHio.cc"
- #include "LPTdag.cc"
- typedef WeightedEdge EDGE;
- typedef DenseGRAPH<EDGE> GRAPH;
- int main(int argc, char *argv[])
- { int i, s, t, N = atoi(argv[1]);
- double duration[N];
- GRAPH G(N, true);
- for (int i = 0; i < N; i++)
- cin >> duration[i];
- while (cin >> s >> t)
- G.insert(new EDGE(s, t, duration[s]));
- LPTdag<GRAPH, EDGE> lpt(G);
- for (i = 0; i < N; i++)
- cout << i << " " << lpt.dist(i) << endl;
- }
- -----
- SPT(Graph &G, int s) : G(G),
- spt(G.V()), wt(G.V(), G.V())
- { QUEUE<int> Q; int N = 0;
- wt[s] = 0.0;
- Q.put(s); Q.put(G.V());
- while (!Q.empty())
- { int v;
- while ((v = Q.get()) == G.V())
- { if (N++ > G.V()) return; Q.put(G.V()); }
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- { int w = e->w();
- double P = wt[v] + e->wt();
- if (P < wt[w])
- { wt[w] = P; Q.put(w); spt[w] = e; }
- }
- }
- }
- ----------
- CHAPTER 22. Network Flow
- -----
- template <class Graph, class Edge> class check
- {
- public:
- static int flow(Graph &G, int v)
- { int x = 0;
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- x += e->from(v) ? e->flow() : -e->flow();
- return x;
- }
- static bool flow(Graph &G, int s, int t)
- {
- for (int v = 0; v < G.V(); v++)
- if ((v != s) && (v != t))
- if (flow(G, v) != 0) return false;
- int sflow = flow(G, s);
- if (sflow < 0) return false;
- if (sflow + flow(G, t) != 0) return false;
- return true;
- }
- };
- -----
- class EDGE
- { int pv, pw, pcap, pflow;
- public:
- EDGE(int v, int w, int cap) :
- pv(v), pw(w), pcap(cap), pflow(0) { }
- int v() const { return pv; }
- int w() const { return pw; }
- int cap() const { return pcap; }
- int flow() const { return pflow; }
- bool from (int v) const
- { return pv == v; }
- int other(int v) const
- { return from(v) ? pw : pv; }
- int capRto(int v) const
- { return from(v) ? pflow : pcap - pflow; }
- void addflowRto(int v, int d)
- { pflow += from(v) ? -d : d; }
- };
- -----
- template <class Graph, class Edge> class MAXFLOW
- { const Graph &G;
- int s, t;
- vector<int> wt;
- vector<Edge *> st;
- int ST(int v) const { return st[v]->other(v); }
- void augment(int s, int t)
- { int d = st[t]->capRto(t);
- for (int v = ST(t); v != s; v = ST(v))
- if (st[v]->capRto(v) < d)
- d = st[v]->capRto(v);
- st[t]->addflowRto(t, d);
- for (int v = ST(t); v != s; v = ST(v))
- st[v]->addflowRto(v, d);
- }
- bool pfs();
- public:
- MAXFLOW(const Graph &G, int s, int t) : G(G),
- s(s), t(t), st(G.V()), wt(G.V())
- { while (pfs()) augment(s, t); }
- };
- -----
- template <class Graph, class Edge>
- bool MAXFLOW<Graph, Edge>::pfs()
- { PQi<int> pQ(G.V(), wt);
- for (int v = 0; v < G.V(); v++)
- { wt[v] = 0; st[v] = 0; pQ.insert(v); }
- wt[s] = -M; pQ.lower(s);
- while (!pQ.empty())
- { int v = pQ.getmin(); wt[v] = -M;
- if (v == t || (v != s && st[v] == 0)) break;
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- { int w = e->other(v);
- int cap = e->capRto(w);
- int P = cap < -wt[v] ? cap : -wt[v];
- if (cap > 0 && -P < wt[w])
- { wt[w] = -P; pQ.lower(w); st[w] = e; }
- }
- }
- return st[t] != 0;
- }
- -----
- template <class Graph, class Edge> class MAXFLOW
- { const Graph &G;
- int s, t;
- vector<int> h, wt;
- void initheights();
- public:
- MAXFLOW(const Graph &G, int s, int t) : G(G),
- s(s), t(t), h(G.V()), wt(G.V(), 0)
- { initheights();
- GQ gQ(G.V());
- gQ.put(s); wt[t] = -(wt[s] = M*G.V());
- while (!gQ.empty())
- { int v = gQ.get();
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- { int w = e->other(v);
- int cap = e->capRto(w);
- int P = cap < wt[v] ? cap : wt[v];
- if (P > 0 && v == s || h[v] == h[w]+1)
- { e->addflowRto(w, P);
- wt[v] -= P; wt[w] += P;
- if ((w != s) && (w != t)) gQ.put(w); }
- }
- if (v != s && v != t && wt[v] > 0)
- { h[v]++; gQ.put(v); }
- }
- }
- };
- -----
- #include "MAXFLOW.cc"
- template <class Graph, class Edge> class FEASIBLE
- { const Graph &G;
- void freeedges(const Graph &F, int v)
- { typename Graph::adjIterator A(F, v);
- for (EDGE* e = A.beg(); !A.end(); e = A.nxt())
- delete e;
- }
- public:
- FEASIBLE(const Graph &G, vector<int> sd) : G(G)
- {
- Graph F(G.V()+2);
- for (int v = 0; v < G.V(); v++)
- {
- typename Graph::adjIterator A(G, v);
- for (EDGE* e = A.beg(); !A.end(); e = A.nxt())
- F.insert(e);
- }
- int s = G.V(), t = G.V()+1;
- for (int i = 0; i < G.V(); i++)
- if (sd[i] >= 0)
- F.insert(new EDGE(s, i, sd[i]));
- else
- F.insert(new EDGE(i, t, -sd[i]));
- MAXFLOW<Graph, Edge>(F, s, t);
- freeedges(F, s); freeedges(F, t);
- }
- };
- -----
- #include "GRAPHbasic.cc"
- #include "MAXFLOW.cc"
- int main(int argc, char *argv[])
- { int s, t, N = atoi(argv[1]);
- GRAPH<EDGE> G(2*N+2);
- for (int i = 0; i < N; i++)
- G.insert(new EDGE(2*N, i, 1));
- while (cin >> s >> t)
- G.insert(new EDGE(s, t, 1));
- for (int i = N; i < 2*N; i++)
- G.insert(new EDGE(i, 2*N+1, 1));
- MAXFLOW<GRAPH<EDGE>, EDGE>(G, 2*N, 2*N+1);
- for (int i = 0; i < N; i++)
- {
- GRAPH<EDGE>::adjIterator A(G, i);
- for (EDGE* e = A.beg(); !A.end(); e = A.nxt())
- if (e->flow() == 1 && e->from(i))
- cout << e->v() << "-" << e->w() << endl;
- }
- }
- -----
- static int cost(Graph &G)
- { int x = 0;
- for (int v = 0; v < G.V(); v++)
- {
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- if (e->from(v) && e->costRto(e->w()) < C)
- x += e->flow()*e->costRto(e->w());
- }
- return x;
- }
- -----
- template <class Graph, class Edge> class MINCOST
- { const Graph &G;
- int s, t;
- vector<int> wt;
- vector <Edge *> st;
- int ST(int v) const;
- void augment(int, int);
- int negcyc(int);
- int negcyc();
- public:
- MINCOST(const Graph &G, int s, int t) : G(G),
- s(s), t(t), st(G.V()), wt(G.V())
- { MAXFLOW<Graph, Edge>(G, s, t);
- for (int x = negcyc(); x != -1; x = negcyc())
- { augment(x, x); }
- }
- };
- -----
- int phiR(int v)
- {
- if (mark[v] == valid) return phi[v];
- phi[v] = phiR(ST(v)) - st[v]->costRto(v);
- mark[v] = valid;
- return phi[v];
- }
- -----
- int lca(int v, int w)
- { mark[v] = ++valid; mark[w] = valid;
- while (v != w)
- {
- if (v != t) v = ST(v);
- if (v != t && mark[v] == valid) return v;
- mark[v] = valid;
- if (w != t) w = ST(w);
- if (w != t && mark[w] == valid) return w;
- mark[w] = valid;
- }
- return v;
- }
- Edge *augment(Edge *x)
- { int v = x->v(), w = x->w(); int r = lca(v, w);
- int d = x->capRto(w);
- for (int u = w; u != r; u = ST(u))
- if (st[u]->capRto(ST(u)) < d)
- d = st[u]->capRto(ST(u));
- for (int u = v; u != r; u = ST(u))
- if (st[u]->capRto(u) < d)
- d = st[u]->capRto(u);
- x->addflowRto(w, d); Edge* e = x;
- for (int u = w; u != r; u = ST(u))
- { st[u]->addflowRto(ST(u), d);
- if (st[u]->capRto(ST(u)) == 0) e = st[u]; }
- for (int u = v; u != r; u = ST(u))
- { st[u]->addflowRto(u, d);
- if (st[u]->capRto(u) == 0) e = st[u]; }
- return e;
- }
- -----
- bool onpath(int a, int b, int c)
- {
- for (int i = a; i != c; i = ST(i))
- if (i == b) return true;
- return false;
- }
- void reverse(int u, int x)
- { Edge *e = st[u];
- for (int i = ST(u); i != x; i = ST(i))
- { Edge *y = st[i]; st[i] = e; e = y; }
- }
- void update(Edge *w, Edge *y)
- { int u = y->w(), v = y->v(), x = w->w();
- if (st[x] != w) x = w->v();
- int r = lca(u, v);
- if (onpath(u, x, r))
- { reverse(u, x); st[u] = y; return; }
- if (onpath(v, x, r))
- { reverse(v, x); st[v] = y; return; }
- }
- -----
- int costR(Edge *e, int v)
- { int R = e->cost() + phi[e->w()] - phi[e->v()];
- return e->from(v) ? R : -R; }
- Edge *besteligible()
- { Edge *x = 0;
- for (int v = 0, min = C*G.V(); v < G.V(); v++)
- {
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- if (e->capRto(e->other(v)) > 0)
- if (e->capRto(v) == 0)
- if (costR(e, v) < min)
- { x = e; min = costR(e, v); }
- }
- return x;
- }
- -----
- template <class Graph, class Edge> class MINCOST
- { const Graph &G; int s, t; int valid;
- vector<Edge *> st; vector<int> mark, phi;
- void dfsR(Edge);
- int ST(int);
- int phiR(int);
- int lca(int, int); Edge *augment(Edge *);
- bool onpath(int, int, int);
- void reverse(int, int);
- void update(Edge *, Edge *);
- int costR(Edge *, int); Edge *besteligible();
- public:
- MINCOST(Graph &G, int s, int t) : G(G), s(s), t(t)
- st(G.V()), mark(G.V(), -1), phi(G.V())
- {
- Edge *z = new EDGE(s, t, M*G.V(), C*G.V());
- G.insert(z);
- z->addflowto(t, z->cap());
- dfsR(z);
- for (valid = 1; ; valid++ )
- {
- phi[t] = z->costRto(s); mark[t] = valid;
- for (int v = 0; v < G.V(); v++)
- if (v != t) phi[v] = phiR(v);
- Edge *x = besteligible();
- if (costR(x, x->v()) == 0) break;
- update(augment(x), x);
- }
- G.remove(z); delete z;
- }
- -----
- int old = 0;
- for (valid = 1; valid != old; )
- {
- old = valid;
- for (int v = 0; v < G.V(); v++)
- {
- typename Graph::adjIterator A(G, v);
- for (Edge* e = A.beg(); !A.end(); e = A.nxt())
- if (e->capRto(e->other(v)) > 0)
- if (e->capRto(v) == 0)
- { update(augment(e), e); valid++; }
- }
- }
Add Comment
Please, Sign In to add comment