⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 algorithms in c++, third edition,part 5,code.txt

📁 Robert Sedgewick的不朽之作《Algorithms》
💻 TXT
📖 第 1 页 / 共 3 页
字号:
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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -