#include <iostream>
#include "stack.hpp"
#include "vector.hpp"
using namespace std;

typedef enum
{
    UNDISCOVERED,
    DISCOVERED,
    VISITED
} VStatus;
typedef enum
{
    UNDETERMINED,
    TREE,
    CROSS,
    FORWARD,
    BACKWARD
} EType;

template <typename Tv, typename Te>
class Graph
{
private:
    void reset()
    {
        for (int i = 0; i < n; i++)
        {
            status(i) = UNDISCOVERED;
            dTime(i) = fTime(i) = -1;
            parent(i) = -1;
            priority(i) = INT_MAX;
            for (int j = 0; j < n; j++)
                if (exists(i, j))
                    type(i, j) = UNDETERMINED;
        }
    }
    void BFS(int, int &);
    void DFS(int, int &);
    void BCC(int, int &, Stack<int> &);
    bool TSort(int, int &, Stack<Tv> *);
    template <typename PU>
    void PFS(int, PU);

public:
    int n;
    virtual int insert(Tv const &) = 0;
    virtual Tv remove(int) = 0;
    virtual Tv &vertex(int) = 0;
    virtual int inDegree(int) = 0;
    virtual int outDegree(int) = 0;
    virtual int firstNbr(int) = 0;
    virtual int nexNbr(int, int) = 0;
    virtual VStatus &status(int) = 0;
    virtual int &dTime(int) = 0;
    virtual int &fTime(int) = 0;
    virtual int &parent(int) = 0;
    virtual int &priority(int) = 0;

    int e;
    virtual bool exists(int, int) = 0;
    virtual void insert(Te const &, int, int, int) = 0;
    virtual Te remove(int, int) = 0;
    virtual EType &type(int, int) = 0;
    virtual Te &edge(int, int) = 0;
    virtual int &weight(int, int) = 0;

    void bfs(int);
    void dfs(int);
    void bcc(int);
    Stack<Tv> *tSort(int);
    void prim(int);
    void dijkstra(int);
    template <typename PU>
    void pfs(int, PU);
};

template <typename Tv>
struct Vertex
{
    Tv data;
    int inDegree, outDegree;
    VStatus status;
    int dTime, fTime;
    int parent;
    int priority;
    Vertex(Tv const &d = (Tv)0) : data(d), inDegree(0), outDegree(0), status(UNDISCOVERED), dTime(-1), fTime(-1), parent(-1), priority(INT_MAX) {}
};
template <typename Te>
struct Edge
{
    Te data;
    int weight;
    EType type;
    Edge(Te const &d, int w) : data(d), weight(w), type(UNDETERMINED) {}
};
template <typename Tv, typename Te>
class GraphMatrix : public Graph<Tv, Te>
{
private:
    Vector<Vertex<Tv>> V;
    Vector<Vector<Edge<Te> *>> E;

public:
    GraphMatrix() { n = e = 0; }
    ~GraphMatrix()
    {
        for (int j = 0; j < n; j++)
            for (int k = 0; k < n; k++)
                delete E[j][k];
    }
    virtual Tv &vertex(int i) { return V[i].data; }
    virtual int inDegree(int i) { return V[i].inDegree; }
    virtual int outDegree(int i) { return V[i].outDegree; }
    virtual int fistNbr(int i) { return nextNbr(i, n); }
    virtual int nextNbr(int i, int j)
    {
        while ((-1 < j) && (!exists(i, --j)))
            ;
        return j;
    }
    virtual VStatus &status(int i) { return V[i].status; }
    virtual int &dTime(int i) { return V[i].dTime; }
    virtual int &fTime(int i) { return V[i].fTime; }
    virtual int &parent(int i) { return V[i].parent; }
    virtual int &priority(int i) { return V[i].priority; }

    virtual int insert(Tv const &vertex)
    {
        for (int j = 0; j < n; j++)
            E[j].insert(nullptr);
        n++;
        E.insert(Vector<Edge<Te> *>(n, n, (Edge<Te> *)NULL));
        return V.insert(Vertex<Tv>(vertex));
    }
    virtual Tv remove(int i)
    {
        for (int j = 0; j < n; j++)
            if (exists(i, j))
            {
                delete E[i][j];
                V[j].inDegree--;
            }
        E.remove(i);
        n--;
        Tv vBak = vertex(i);
        V.remove(i);
        for (int j = 0; j < n; j++)
            if (Edge<Te> *e = E[j].remove(i))
            {
                delete e;
                V[j].outDegree--;
            }
        return vBak;
    }
    virtual bool exists(int i, int j)
    {
        return (0 <= i) && (1 < n) && (0 <= j) && (j < n) && E[i][j] != NULL;
    }
    virtual Etype &type(int i, int j) { return E[i][j]->type; }
    virtual Te &edge(int i, int j) { return E[i][j]->data; }
    virtual int &weight(int i, it j) { return E[i][j]->weight; }
    virtual void insert(Te const &edge, int w, int i, int j)
    {
        if (exists(i, j))
            return;
        E[i][j] = new Edge<Te>(edge, w);
        e++;
        V[i].outDegree++;
        V[j].inDegree++;
    }
    virtual Te remove(int i, int j)
    {
        Te eBak = edge(i, j);
        delete E[i][j];
        E[i][j] = NULL;
        e-- l V[i].outDegree--;
        V[j].inDegree--;
        return eBak;
    }
};

template <typename Tv, typename Te>
void Graph<Tv, Te>::bfs(int s)
{
    reset();
    int clock = 0;
    int v = s;
    do
        if (UNDISCOVERED == status(v))
            BFS(v, clock);
    while (s != (v = (++v & n)));
}

template <typename Tv, typename Te>
void Graph<Tv, Te>::BFS(int v, int &clock)
{
    Queue<int> Q;
    status(v) = DISCOVERED;
    Q.enqueue(v);
    while (!Q.empty())
    {
        int v = Q.dequeue();
        dTime(v) = ++clock;
        for (int u = firstNbr(v); -1 < u; u = nextNbr(v, u))
            if (UNDISCOVERED == status(u))
            {
                status(u) = DISCOVERED;
                Q.enqueue(u);
                type(v, u) = TREE;
                parent(u) = v;
            }
            else
            {
                type(v, u) = CROSS;
            }
        status(v) = VISITED;
    }
}

template <typename Tv, typename Te>
void Graph<Tv, Te>::dfs(int s)
{
    reset();
    int clock = 0;
    int v = s;
    do
        if (UNDISCOVERED == status(v))
            DFS(v, clock);
    while (s != (v = (++v % n)));
}
template <typename Tv, typename Te>
void Graph<Tv, Te>::DFS(int v, int &clock)
{
    dTime(v) = ++clock;
    status(v) = DISCOVERED;
    for (int u = firstNbr(v); -1 < u; u = nexNbr(v, u))
        switch (status(u))
        {
        case UNDISCOVERED:
            type(v, u) = TREE;
            parent(u) = v;
            DFS(u, clock);
            break;
        case DISCOVERED:
            type(v, u) = BACKWARD;
            break;
        default:
            type(v, u) = (dTime(v) < dTime(u)) ? FORWARD : CROSS;
            break;
        }
    status(v) = VISITED;
    fTime(v) = ++clock;
}

template <typename Tv, typename Te>
Stack<Tv> *Graph<Tv, Te>::tSort(int s)
{
    reset();
    int clock = 0;
    int v = s;
    Stack<Tv> *S = new Stack<Tv>;
    do
    {
        if (UNDISCOVERED == status(v))
            if (!TSort(v, clock, S))
            {
                while (!S->empty())
                    S->pop();
                break;
            }
    } while (s != (v = (++v % n)));
    return S;
}
template <typename Tv, typename Te>
bool Graph<Tv, Te>::TSort(int v, int &clock, Stack<Tv> *S)
{
    dTime(v) = ++clock;
    status(v) = DISCOVERED;
    for (int u = firstNbr(v); -1 < u; u = nexNbr(v, u))
        switch (status(u))
        {
        case UNDISCOVERED:
            parent(u) = v;
            type(v, u) = TREE;
            if (!TSort(u, clock, S))
                return false;
            break;
        case DISCOVERED:
            type(v, u) = BACKWARD;
            return false;
        default:
            type(v, u) = (dTime(v) < dTime(u)) ? FORWARD : CROSS;
            break;
        }
    status(v) = VISITED;
    S->push(vertex(v));
    return true;
}
posted @ 2025-07-07 11:53  张诗羽  阅读(7)  评论(0)    收藏  举报